NEST main@d22e9b2
 
Loading...
Searching...
No Matches
hh_psc_alpha.h
Go to the documentation of this file.
1/*
2 * hh_psc_alpha.h
3 *
4 * This file is part of NEST.
5 *
6 * Copyright (C) 2004 The NEST Initiative
7 *
8 * NEST is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * NEST is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with NEST. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23#ifndef HH_PSC_ALPHA_H
24#define HH_PSC_ALPHA_H
25
26// Generated includes:
27#include "config.h"
28
29#ifdef HAVE_GSL
30
31// External includes:
32#include <gsl/gsl_errno.h>
33#include <gsl/gsl_matrix.h>
34#include <gsl/gsl_odeiv.h>
35#include <gsl/gsl_sf_exp.h>
36
37// Includes from nestkernel:
38#include "archiving_node.h"
39#include "connection.h"
40#include "event.h"
41#include "nest_types.h"
42#include "recordables_map.h"
43#include "ring_buffer.h"
45
46namespace nest
47{
58extern "C" int hh_psc_alpha_dynamics( double, const double*, double*, void* );
59
60// Disable clang-formatting for documentation due to over-wide tables.
61// clang-format off
62/* BeginUserDocs: neuron, Hodgkin-Huxley, current-based, soft threshold
63
64Short description
65+++++++++++++++++
66
67Hodgkin-Huxley neuron model
68
69Description
70+++++++++++
71
72``hh_psc_alpha`` is an implementation of a spiking neuron using the Hodgkin-Huxley
73formalism :footcite:p:`Hodgkin1952`, with
74
75* membrane dynamics governed by sodium, potassium, and leak currents,
76* :math:`\alpha`-shaped synaptic input currents,
77* spike detection by a combined threshold-and-local-maximum search.
78
79The Hodgkin-Huxley formalism is also described in standard textbooks
80:footcite:p:`Gerstner2002`, :footcite:p:`Dayan2001`.
81
82Membrane potential and channel dynamics
83.......................................
84
85The membrane potential evolves according to
86
87.. math::
88
89 C_{\text{m}} \frac{dV_\text{m}}{dt} = -(I_{\text{Na}} + I_{\text{K}} + I_{\text{L}}) + I_{\text{syn}} + I_\text{e}
90
91with the voltage-gated sodium current, the delayed-rectifier potassium current, and the
92leak current
93
94.. math::
95
96 I_{\text{Na}} &= g_{\text{Na}} \, m^3 h \, (V_\text{m} - E_{\text{Na}}) \\
97 I_{\text{K}} &= g_{\text{K}} \, n^4 \, (V_\text{m} - E_{\text{K}}) \\
98 I_{\text{L}} &= g_{\text{L}} \, (V_\text{m} - E_{\text{L}}) \;.
99
100The gating variables :math:`m`, :math:`h`, and :math:`n` follow
101
102.. math::
103
104 \frac{dx}{dt} = \alpha_x(V_\text{m}) (1 - x) - \beta_x(V_\text{m}) \, x, \quad x \in \{m, h, n\} \;,
105
106with voltage-dependent rates (:math:`V_\text{m}` in mV)
107
108.. math::
109
110 \alpha_m &= \frac{0.1 (V_\text{m} + 40)}{1 - e^{-(V_\text{m} + 40)/10}} \\
111 \beta_m &= 4 \, e^{-(V_\text{m} + 65)/18} \\
112 \alpha_h &= 0.07 \, e^{-(V_\text{m} + 65)/20} \\
113 \beta_h &= \frac{1}{1 + e^{-(V_\text{m} + 35)/10}} \\
114 \alpha_n &= \frac{0.01 (V_\text{m} + 55)}{1 - e^{-(V_\text{m} + 55)/10}} \\
115 \beta_n &= 0.125 \, e^{-(V_\text{m} + 65)/80} \;.
116
117Spike detection is done by a combined threshold-and-local-maximum search: if there is a
118local maximum of the membrane potential above a certain threshold, it is considered a spike.
119
120Synaptic input
121..............
122
123The total synaptic input current :math:`I_{\text{syn}}` entering the voltage equation above has an
124excitatory and an inhibitory component,
125
126.. math::
127
128 I_{\text{syn}}(t) = I_{\text{syn, ex}}(t) + I_{\text{syn, in}}(t) \;.
129
130Each incoming spike evokes an :math:`\alpha`-shaped post-synaptic current
131
132.. math::
133
134 i_{\text{syn, X}}(t) = \frac{e}{\tau_{\text{syn, X}}} t e^{-\frac{t}{\tau_{\text{syn, X}}}} \Theta(t) \;,
135
136for :math:`\text{X} \in \{\text{ex}, \text{in}\}`, with :math:`\Theta(x)` the Heaviside step function. The
137currents are normalized such that an event of weight 1.0 evokes a peak current of 1 pA at
138:math:`t = \tau_{\text{syn, X}}`.
139
140Each channel current is the sum of these single-spike responses over
141all presynaptic neurons :math:`j` and their spike times :math:`t_j^k`, weighted by the synaptic weights
142:math:`w_j` and :math:`d_j` is the delay from neuron :math:`j`:
143
144.. math::
145
146 I_{\text{syn, X}}(t) = \sum_j w_j \sum_k i_{\text{syn, X}}(t - t_j^k-d_j) \;.
147
148Excitatory and inhibitory inputs are distinguished by the sign of the synaptic weight.
149
150For details on asynchronicity in spike and firing events with Hodgkin Huxley models
151see :ref:`here <hh_details>`.
152
153Parameters
154++++++++++
155
156The following parameters can be set in the status dictionary.
157
158============== =========== ============================= ===================================================
159**Parameter** **Default** **Math equivalent** **Description**
160============== =========== ============================= ===================================================
161``E_L`` -54.402 mV :math:`E_\text{L}` Leak reversal potential
162``C_m`` 100 pF :math:`C_{\text{m}}` Capacity of the membrane
163``t_ref`` 2 ms :math:`t_{\text{ref}}` Duration of refractory period
164``g_L`` 30 nS :math:`g_\text{L}` Leak conductance
165``E_Na`` 50 mV :math:`E_{\text{Na}}` Sodium reversal potential
166``g_Na`` 12000 nS :math:`g_{\text{Na}}` Sodium peak conductance
167``E_K`` -77 mV :math:`E_{\text{K}}` Potassium reversal potential
168``g_K`` 3600 nS :math:`g_{\text{K}}` Potassium peak conductance
169``tau_syn_ex`` 0.2 ms :math:`\tau_{\text{syn, ex}}` Rise time of the excitatory input current
170``tau_syn_in`` 2.0 ms :math:`\tau_{\text{syn, in}}` Rise time of the inhibitory input current
171``I_e`` 0 pA :math:`I_\text{e}` Constant input current
172============== =========== ============================= ===================================================
173
174The following state variables evolve during simulation and are available either as neuron properties or as recordables.
175
176================== =========================== ========================== =================================
177**State variable** **Initial value** **Math equivalent** **Description**
178================== =========================== ========================== =================================
179``V_m`` -65 mV :math:`V_{\text{m}}` Membrane potential
180``Act_m`` :math:`m_\infty` [#steady]_ :math:`m` Sodium activation variable
181``Inact_h`` :math:`h_\infty` [#steady]_ :math:`h` Sodium inactivation variable
182``Act_n`` :math:`n_\infty` [#steady]_ :math:`n` Potassium activation variable
183``I_syn_ex`` 0 pA :math:`I_{\text{syn, ex}}` Excitatory synaptic input current
184``I_syn_in`` 0 pA :math:`I_{\text{syn, in}}` Inhibitory synaptic input current
185================== =========================== ========================== =================================
186
187.. [#steady] The gating variables are initialized to their steady-state values
188 :math:`x_\infty = \alpha_x / (\alpha_x + \beta_x)` at :math:`V_\text{m} = -65` mV.
189
190Problems/Todo
191+++++++++++++
192
193- better spike detection
194- initial wavelet/spike at simulation onset
195
196References
197++++++++++
198
199
200.. footbibliography::
201
202Sends
203+++++
204
205SpikeEvent
206
207Receives
208++++++++
209
210SpikeEvent, CurrentEvent, DataLoggingRequest
211
212See also
213++++++++
214
215hh_cond_exp_traub
216
217Examples using this model
218+++++++++++++++++++++++++
219
220.. listexamples:: hh_psc_alpha
221
222EndUserDocs */
223// clang-format on
224
225void register_hh_psc_alpha( const std::string& name );
226
227class hh_psc_alpha : public ArchivingNode
228{
229
230public:
231 hh_psc_alpha();
232 hh_psc_alpha( const hh_psc_alpha& );
233 ~hh_psc_alpha() override;
234
240 using Node::handle;
241 using Node::handles_test_event;
242
243 size_t send_test_event( Node&, size_t, synindex, bool ) override;
244
245 void handle( SpikeEvent& ) override;
246 void handle( CurrentEvent& ) override;
247 void handle( DataLoggingRequest& ) override;
248
249 size_t handles_test_event( SpikeEvent&, size_t ) override;
250 size_t handles_test_event( CurrentEvent&, size_t ) override;
251 size_t handles_test_event( DataLoggingRequest&, size_t ) override;
252
253 void get_status( Dictionary& ) const override;
254 void set_status( const Dictionary& ) override;
255
256private:
257 void init_buffers_() override;
258 void pre_run_hook() override;
259 void update( Time const&, const long, const long ) override;
260
261 // END Boilerplate function declarations ----------------------------
262
263 // Friends --------------------------------------------------------
264
265 // make dynamics function quasi-member
266 friend int hh_psc_alpha_dynamics( double, const double*, double*, void* );
267
268 // The next two classes need to be friend to access the State_ class/member
269 friend class RecordablesMap< hh_psc_alpha >;
270 friend class UniversalDataLogger< hh_psc_alpha >;
271
272private:
273 // ----------------------------------------------------------------
274
276 struct Parameters_
277 {
278 double t_ref_;
279 double g_Na;
280 double g_K;
281 double g_L;
282 double C_m;
283 double E_Na;
284 double E_K;
285 double E_L;
286 double tau_synE;
287 double tau_synI;
288 double I_e;
289
290 Parameters_();
291
292 void get( Dictionary& ) const;
293 void set( const Dictionary&, Node* node );
294 };
295
296public:
297 // ----------------------------------------------------------------
298
303 struct State_
304 {
311 enum StateVecElems
312 {
313 V_M = 0,
314 HH_M, // 1
315 HH_H, // 2
316 HH_N, // 3
317 DI_EXC, // 4
318 I_EXC, // 5
319 DI_INH, // 6
320 I_INH, // 7
321 STATE_VEC_SIZE
322 };
323
324
326 double y_[ STATE_VEC_SIZE ];
327 int r_;
328
329 State_( const Parameters_& );
330 State_( const State_& );
331
332 State_& operator=( const State_& );
333
334 void get( Dictionary& ) const;
335 void set( const Dictionary&, Node* node );
336 };
337
338 // ----------------------------------------------------------------
339
340private:
344 struct Buffers_
345 {
346 Buffers_( hh_psc_alpha& );
347 Buffers_( const Buffers_&, hh_psc_alpha& );
348
350 UniversalDataLogger< hh_psc_alpha > logger_;
351
353 RingBuffer spike_exc_;
354 RingBuffer spike_inh_;
355 RingBuffer currents_;
356
358 gsl_odeiv_step* s_;
359 gsl_odeiv_control* c_;
360 gsl_odeiv_evolve* e_;
361 gsl_odeiv_system sys_;
362
363 // Since IntegrationStep_ is initialized with step_, and the resolution
364 // cannot change after nodes have been created, it is safe to place both
365 // here.
366 double step_;
367 double IntegrationStep_;
368
376 double I_stim_;
377 };
378
379 // ----------------------------------------------------------------
380
384 struct Variables_
385 {
387 double PSCurrInit_E_;
388
390 double PSCurrInit_I_;
391
392 int RefractoryCounts_;
393 };
394
395 // Access functions for UniversalDataLogger -------------------------------
396
398 template < State_::StateVecElems elem >
399 double
400 get_y_elem_() const
401 {
402 return S_.y_[ elem ];
403 }
404
405 // ----------------------------------------------------------------
406
407 Parameters_ P_;
408 State_ S_;
409 Variables_ V_;
410 Buffers_ B_;
411
413 static RecordablesMap< hh_psc_alpha > recordablesMap_;
414};
415
416
417inline size_t
418hh_psc_alpha::send_test_event( Node& target, size_t receptor_type, synindex, bool )
419{
420 SpikeEvent e;
421 e.set_sender( *this );
422
423 return target.handles_test_event( e, receptor_type );
424}
425
426
427inline size_t
428hh_psc_alpha::handles_test_event( SpikeEvent&, size_t receptor_type )
429{
430 if ( receptor_type != 0 )
431 {
432 throw UnknownReceptorType( receptor_type, get_name() );
433 }
434 return 0;
435}
436
437inline size_t
438hh_psc_alpha::handles_test_event( CurrentEvent&, size_t receptor_type )
439{
440 if ( receptor_type != 0 )
441 {
442 throw UnknownReceptorType( receptor_type, get_name() );
443 }
444 return 0;
445}
446
447inline size_t
448hh_psc_alpha::handles_test_event( DataLoggingRequest& dlr, size_t receptor_type )
449{
450 if ( receptor_type != 0 )
451 {
452 throw UnknownReceptorType( receptor_type, get_name() );
453 }
454 return B_.logger_.connect_logging_device( dlr, recordablesMap_ );
455}
456
457inline void
458hh_psc_alpha::get_status( Dictionary& d ) const
459{
460 P_.get( d );
461 S_.get( d );
463
464 d[ names::recordables ] = recordablesMap_.get_list();
465}
466
467inline void
468hh_psc_alpha::set_status( const Dictionary& d )
469{
470 Parameters_ ptmp = P_; // temporary copy in case of errors
471 ptmp.set( d, this ); // throws if BadProperty
472 State_ stmp = S_; // temporary copy in case of errors
473 stmp.set( d, this ); // throws if BadProperty
474
475 // We now know that (ptmp, stmp) are consistent. We do not
476 // write them back to (P_, S_) before we are also sure that
477 // the properties to be set in the parent class are internally
478 // consistent.
480
481 // if we get here, temporaries contain consistent set of properties
482 P_ = ptmp;
483 S_ = stmp;
484}
485
486} // namespace
487
488#endif // HAVE_GSL
489#endif // HH_PSC_ALPHA_H
Dictionary class for interface to Python and C++ API.
Definition dictionary.h:213
void get_status(Dictionary &d) const override
Export properties of the node by setting entries in the status dictionary.
Definition archiving_node.cpp:220
void set_status(const Dictionary &d) override
Change properties of the node according to the entries in the dictionary.
Definition archiving_node.cpp:236
const std::string E_L("E_L")
const std::string I_e("I_e")
const std::string E_K("E_K")
const std::string recordables("recordables")
const std::string C_m("C_m")
const std::string d("d")
const std::string g_Na("g_Na")
const std::string E_Na("E_Na")
const std::string g_K("g_K")
const std::string target("target")
const std::string g_L("g_L")
Namespace for the NEST simulation kernel.
Definition beta_normalization_factor.h:33
size_t synindex
For enumerations of synapse types.
Definition nest_types.h:115
const double e
Definition numerics.cpp:32