MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
SpikeGen.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 ** This program is part of 'MOOSE', the
3 ** Messaging Object Oriented Simulation Environment.
4 ** Copyright (C) 2003-2007 Upinder S. Bhalla. and NCBS
5 ** It is made available under the terms of the
6 ** GNU Lesser General Public License version 2.1
7 ** See the file COPYING.LIB for the full notice.
8 **********************************************************************/
9 
10 #include "header.h"
11 #include "SpikeGen.h"
12 
14  // MsgSrc definitions
17  static SrcFinfo1< double > spikeOut( "spikeOut",
18  "Sends out a trigger for an event.");
19  return &spikeOut;
20 }
21 
23 {
25  // Shared message definitions
27  static DestFinfo process( "process",
28  "Handles process call",
30  static DestFinfo reinit( "reinit",
31  "Handles reinit call",
33 
34  static Finfo* processShared[] =
35  {
36  &process, &reinit
37  };
38 
39  static SharedFinfo proc( "proc",
40  "Shared message to receive Process message from scheduler",
41  processShared, sizeof( processShared ) / sizeof( Finfo* ) );
42 
44  // Dest Finfos.
46  static DestFinfo Vm( "Vm",
47  "Handles Vm message coming in from compartment",
49 
51  // Value Finfos.
53 
54  static ValueFinfo< SpikeGen, double > threshold( "threshold",
55  "Spiking threshold, must cross it going up",
58  );
59  static ValueFinfo< SpikeGen, double > refractT( "refractT",
60  "Refractory Time.",
63  );
64  static ValueFinfo< SpikeGen, double > absRefract( "abs_refract",
65  "Absolute refractory time. Synonym for refractT.",
68  );
69  static ReadOnlyValueFinfo< SpikeGen, bool > hasFired( "hasFired",
70  "True if SpikeGen has just fired",
72  );
73  static ValueFinfo< SpikeGen, bool > edgeTriggered( "edgeTriggered",
74  "When edgeTriggered = 0, the SpikeGen will fire an event in each "
75  "timestep while incoming Vm is > threshold and at least abs_refract"
76  "time has passed since last event. This may be problematic if the "
77  "incoming Vm remains above threshold for longer than abs_refract. "
78  "Setting edgeTriggered to 1 resolves this as the SpikeGen generates"
79  "an event only on the rising edge of the incoming Vm and will "
80  "remain idle unless the incoming Vm goes below threshold.",
83  );
84 
85  static Finfo* spikeGenFinfos[] =
86  {
87  spikeOut(), // SrcFinfo
88  &proc, // Shared
89  &Vm, // Dest
90  &threshold, // Value
91  &refractT, // Value
92  &absRefract, // Value
93  &hasFired, // ReadOnlyValue
94  &edgeTriggered, // Value
95 
96  };
97 
98  static string doc[] =
99  {
100  "Name", "SpikeGen",
101  "Author", "Upi Bhalla",
102  "Description", "SpikeGen object, for detecting threshold crossings."
103  "The threshold detection can work in multiple modes.\n "
104  "If the refractT < 0.0, then it fires an event only at the rising "
105  "edge of the input voltage waveform"
106  };
107  static Dinfo< SpikeGen > dinfo;
108  static Cinfo spikeGenCinfo(
109  "SpikeGen",
111  spikeGenFinfos, sizeof( spikeGenFinfos ) / sizeof( Finfo* ),
112  &dinfo,
113  doc,
114  sizeof(doc)/sizeof(string)
115  );
116 
117  return &spikeGenCinfo;
118 }
119 
121 
123  : threshold_(0.0),
124  refractT_(0.0),
125  lastEvent_(0.0),
126  V_(0.0),
127  fired_( 0 ),
128  edgeTriggered_(1)
129 {;}
130 
132 // Here we put the SpikeGen class functions.
134 
135 // Value Field access function definitions.
136 void SpikeGen::setThreshold( double threshold )
137 {
138  threshold_ = threshold;
139 }
141 {
142  return threshold_;
143 }
144 
145 void SpikeGen::setRefractT( double val )
146 {
147  refractT_ = val;
148 }
149 double SpikeGen::getRefractT() const
150 {
151  return refractT_;
152 }
153 
154 /*
155 void SpikeGen::setAmplitude( double val )
156 {
157  amplitude_ = val;
158 }
159 double SpikeGen::getAmplitude() const
160 {
161  return amplitude_;
162 }
163 
164 void SpikeGen::setState( double val )
165 {
166  state_ = val;
167 }
168 double SpikeGen::getState() const
169 {
170  return state_;
171 }
172 */
173 
174 bool SpikeGen::getFired() const
175 {
176  return fired_;
177 }
178 
180 {
181  edgeTriggered_ = yes;
182 }
184 {
185  return edgeTriggered_;
186 }
187 
189 // SpikeGen::Dest function definitions.
191 
192 void SpikeGen::process( const Eref& e, ProcPtr p )
193 {
194  double t = p->currTime;
195  if ( V_ > threshold_ ) {
196  if ((t + p->dt/2.0) >= (lastEvent_ + refractT_)) {
197  if ( !( edgeTriggered_ && fired_ ) ) {
198  spikeOut()->send( e, t );
199  lastEvent_ = t;
200  fired_ = true;
201  }
202  }
203  } else {
204  fired_ = false;
205  }
206 }
207 
208 // Set it so that first spike is allowed.
209 void SpikeGen::reinit( const Eref& e, ProcPtr p )
210 {
211  lastEvent_ = -refractT_ ;
212 }
213 
214 void SpikeGen::handleVm( double val )
215 {
216  V_ = val;
217 }
218 
220 
221 #ifdef DO_UNIT_TESTS
222 #include "../shell/Shell.h"
223 
224 void testSpikeGen()
225 {
226  Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() );
227  Id sid = shell->doCreate( "SpikeGen", Id(), "spike", 1, MooseGlobal );
228  SpikeGen& sg = *( reinterpret_cast< SpikeGen* >( sid.eref().data() ) );
229 
230  Eref er( sid.eref() );
231  ProcInfo p;
232  p.dt = 0.001;
233  p.currTime = 0.0;
234  sg.setThreshold( 1.0 );
235  sg.setRefractT( 0.005 );
236 
237  sg.reinit( er, &p );
238  sg.handleVm( 0.5 );
239  sg.process( er, &p );
240  assert( !sg.getFired() );
241  p.currTime += p.dt;
242 
243  sg.handleVm( 0.999 );
244  sg.process( er, &p );
245  assert( !sg.getFired() );
246  p.currTime += p.dt;
247 
248  sg.handleVm( 1.001 );
249  sg.process( er, &p );
250  assert( sg.getFired() );
251  p.currTime += p.dt;
252 
253  sg.handleVm( 0.999 );
254  sg.process( er, &p );
255  assert( !sg.getFired() );
256  p.currTime += p.dt;
257 
258  sg.handleVm( 2.0 ); // Too soon, refractory
259  sg.process( er, &p );
260  assert( !sg.getFired() );
261 
262  p.currTime += 0.005; // Now post-refractory
263  sg.handleVm( 2.0 ); // Now not refractory
264  sg.process( er, &p );
265  assert( sg.getFired() );
266 
267  sid.destroy();
268  cout << "." << flush;
269 }
270 #endif
char * data() const
Definition: Eref.cpp:41
double threshold_
Definition: SpikeGen.h:49
double currTime
Definition: ProcInfo.h:19
Definition: Dinfo.h:60
void setThreshold(double threshold)
Definition: SpikeGen.cpp:136
double refractT_
Definition: SpikeGen.h:50
bool getEdgeTriggered() const
Definition: SpikeGen.cpp:183
Eref eref() const
Definition: Id.cpp:125
Id doCreate(string type, ObjId parent, string name, unsigned int numData, NodePolicy nodePolicy=MooseBlockBalance, unsigned int preferredNode=1)
Definition: Shell.cpp:181
static const Cinfo * spikeGenCinfo
Definition: SpikeGen.cpp:120
void destroy() const
Definition: Id.cpp:176
static const Cinfo * initCinfo()
Definition: SpikeGen.cpp:22
double getThreshold() const
Definition: SpikeGen.cpp:140
static SrcFinfo1< double > * spikeOut()
Definition: SpikeGen.cpp:16
void process(const Eref &e, ProcPtr p)
Definition: SpikeGen.cpp:192
double V_
Definition: SpikeGen.h:52
double lastEvent_
Definition: SpikeGen.h:51
double dt
Definition: ProcInfo.h:18
void handleVm(double val)
Definition: SpikeGen.cpp:214
Definition: OpFunc.h:27
Definition: Eref.h:26
void setEdgeTriggered(bool yes)
Definition: SpikeGen.cpp:179
bool edgeTriggered_
Definition: SpikeGen.h:54
Definition: Id.h:17
static const Cinfo * initCinfo()
Definition: Neutral.cpp:16
bool getFired() const
Definition: SpikeGen.cpp:174
void reinit(const Eref &e, ProcPtr p)
Definition: SpikeGen.cpp:209
bool fired_
Definition: SpikeGen.h:53
double getRefractT() const
Definition: SpikeGen.cpp:149
Definition: Cinfo.h:18
Definition: Shell.h:43
Definition: Finfo.h:12
void setRefractT(double val)
Definition: SpikeGen.cpp:145