NEST main@caf0ae8
 
Loading...
Searching...
No Matches
hh_psc_alpha_gap.h
Go to the documentation of this file.
1/*
2 * hh_psc_alpha_gap.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_GAP_H
24#define HH_PSC_ALPHA_GAP_H
25
26#include "config.h"
27
28#ifdef HAVE_GSL
29
30// C includes:
31#include <gsl/gsl_errno.h>
32#include <gsl/gsl_matrix.h>
33#include <gsl/gsl_odeiv.h>
34#include <gsl/gsl_sf_exp.h>
35
36// Includes from nestkernel:
37#include "archiving_node.h"
38#include "connection.h"
39#include "event.h"
40#include "nest_types.h"
41#include "node.h"
42#include "recordables_map.h"
43#include "ring_buffer.h"
45
46namespace nest
47{
48
59extern "C" int hh_psc_alpha_gap_dynamics( double, const double*, double*, void* );
60
61/* BeginUserDocs: neuron, current-based, Hodgkin-Huxley, electrical, soft threshold
62
63Short description
64+++++++++++++++++
65
66Hodgkin-Huxley neuron model with gap-junction support
67
68Description
69+++++++++++
70
71``hh_psc_alpha_gap`` is an implementation of a spiking neuron using the
72Hodgkin-Huxley formalism. In contrast to ``hh_psc_alpha`` the implementation
73additionally supports gap junctions.
74
751. Postsynaptic currents
76Incoming spike events induce a postsynaptic change of current modelled
77by an alpha function. The alpha function is normalized such that an event of
78weight 1.0 results in a peak current of 1 pA.
79
802. Spike Detection
81Spike detection is done by a combined threshold-and-local-maximum search: if
82there is a local maximum above a certain threshold of the membrane potential,
83it is considered a spike.
84
853. Gap Junctions
86Gap Junctions are implemented by a gap current of the form
87:math:`g_{ij}( V_i - V_j)`.
88
89See also :footcite:p:`Gerstner2002`, :footcite:p:`Mancilla2007`, :footcite:p:`Hodgkin1952`, :footcite:p:`Hahne2015`.
90
91For details on asynchronicity in spike and firing events with Hodgkin Huxley models
92see :ref:`here <hh_details>`.
93
94Parameters
95++++++++++
96
97The following parameters can be set in the status Dictionary.
98
99=========== ====== ============================================================
100tau_ex ms Rise time of the excitatory synaptic alpha function
101tau_in ms Rise time of the inhibitory synaptic alpha function
102g_K nS Potassium peak conductance
103V_m mV Membrane potential
104E_L mV Leak reversal potential
105g_L nS Leak conductance
106C_m pF Capacity of the membrane
107t_ref ms Duration of refractory period
108tau_syn_ex ms Rise time of the excitatory synaptic alpha function
109tau_syn_in ms Rise time of the inhibitory synaptic alpha function
110E_Na mV Sodium reversal potential
111g_Na nS Sodium peak conductance
112E_K mV Potassium reversal potential
113g_Kv1 nS Potassium peak conductance
114g_Kv3 nS Potassium peak conductance
115Act_m real Activation variable m
116Inact_h real Inactivation variable h
117Act_n real Activation variable n
118I_e pA External input current
119=========== ====== ============================================================
120
121References
122++++++++++
123
124.. footbibliography::
125
126Sends
127+++++
128
129SpikeEvent, GapJunctionEvent
130
131Receives
132++++++++
133
134SpikeEvent, GapJunctionEvent, CurrentEvent, DataLoggingRequest
135
136See also
137++++++++
138
139hh_psc_alpha, hh_cond_exp_traub, gap_junction
140
141Examples using this model
142+++++++++++++++++++++++++
143
144.. listexamples:: hh_psc_alpha_gap
145
146EndUserDocs */
147
148void register_hh_psc_alpha_gap( const std::string& name );
149
150class hh_psc_alpha_gap : public ArchivingNode
151{
152
153public:
154 typedef Node base;
155
156 hh_psc_alpha_gap();
157 hh_psc_alpha_gap( const hh_psc_alpha_gap& );
158 ~hh_psc_alpha_gap() override;
159
165 using Node::handle;
166 using Node::handles_test_event;
167 using Node::sends_secondary_event;
168
169 size_t send_test_event( Node& target, size_t receptor_type, synindex, bool ) override;
170
171 void handle( SpikeEvent& ) override;
172 void handle( CurrentEvent& ) override;
173 void handle( DataLoggingRequest& ) override;
174 void handle( GapJunctionEvent& ) override;
175
176 size_t handles_test_event( SpikeEvent&, size_t ) override;
177 size_t handles_test_event( CurrentEvent&, size_t ) override;
178 size_t handles_test_event( DataLoggingRequest&, size_t ) override;
179 size_t handles_test_event( GapJunctionEvent&, size_t ) override;
180
181 void
182 sends_secondary_event( GapJunctionEvent& ) override
183 {
184 }
185
186 void get_status( Dictionary& ) const override;
187 void set_status( const Dictionary& ) override;
188
189private:
190 void init_buffers_() override;
191 void pre_run_hook() override;
192
196 bool update_( Time const&, const long, const long, const bool );
197
198 void update( Time const&, const long, const long ) override;
199 bool wfr_update( Time const&, const long, const long ) override;
200
201 // END Boilerplate function declarations ----------------------------
202
203 // Friends --------------------------------------------------------
204
205 // make dynamics function quasi-member
206 friend int hh_psc_alpha_gap_dynamics( double, const double*, double*, void* );
207
208 // The next two classes need to be friend to access the State_ class/member
209 friend class RecordablesMap< hh_psc_alpha_gap >;
210 friend class UniversalDataLogger< hh_psc_alpha_gap >;
211
212private:
213 // ----------------------------------------------------------------
214
216 struct Parameters_
217 {
218 double t_ref_;
219 double g_Na;
220 double g_Kv1;
221 double g_Kv3;
222 double g_L;
223 double C_m;
224 double E_Na;
225 double E_K;
226 double E_L;
227 double tau_synE;
228 double tau_synI;
229 double I_e;
230
231 Parameters_();
232
233 void get( Dictionary& ) const;
234 void set( const Dictionary&, Node* node );
235 };
236
237public:
238 // ----------------------------------------------------------------
239
244 struct State_
245 {
252 enum StateVecElems
253 {
254 V_M = 0,
255 HH_M, // 1
256 HH_H, // 2
257 HH_N, // 3
258 HH_P, // 4
259 DI_EXC, // 5
260 I_EXC, // 6
261 DI_INH, // 7
262 I_INH, // 8
263 STATE_VEC_SIZE
264 };
265
267 double y_[ STATE_VEC_SIZE ];
268 int r_;
269
270 State_( const Parameters_& );
271 State_( const State_& );
272
273 State_& operator=( const State_& );
274
275 void get( Dictionary& ) const;
276 void set( const Dictionary&, Node* node );
277 };
278
279 // ----------------------------------------------------------------
280
281private:
285 struct Buffers_
286 {
287 Buffers_( hh_psc_alpha_gap& );
289 Buffers_( const Buffers_&, hh_psc_alpha_gap& );
290
292 UniversalDataLogger< hh_psc_alpha_gap > logger_;
293
295 RingBuffer spike_exc_;
296 RingBuffer spike_inh_;
297 RingBuffer currents_;
298
300 gsl_odeiv_step* s_;
301 gsl_odeiv_control* c_;
302 gsl_odeiv_evolve* e_;
303 gsl_odeiv_system sys_;
304
305 // Since IntegrationStep_ is initialized with step_, and the resolution
306 // cannot change after nodes have been created, it is safe to place both
307 // here.
308 double step_;
309 double IntegrationStep_;
310
311 // remembers current lag for piecewise interpolation
312 long lag_;
313 // remembers y_values from last wfr_update
314 std::vector< double > last_y_values;
315 // summarized gap weight
316 double sumj_g_ij_;
317 // summarized coefficients of the interpolation polynomial
318 std::vector< double > interpolation_coefficients;
319
327 double I_stim_;
328 };
329
330 // ----------------------------------------------------------------
331
335 struct Variables_
336 {
338 double PSCurrInit_E_;
339
341 double PSCurrInit_I_;
342
343 int RefractoryCounts_;
344 };
345
346 // Access functions for UniversalDataLogger -------------------------------
347
349 template < State_::StateVecElems elem >
350 double
351 get_y_elem_() const
352 {
353 return S_.y_[ elem ];
354 }
355
356 // ----------------------------------------------------------------
357
358 Parameters_ P_;
359 State_ S_;
360 Variables_ V_;
361 Buffers_ B_;
362
364 static RecordablesMap< hh_psc_alpha_gap > recordablesMap_;
365};
366
367inline void
368hh_psc_alpha_gap::update( Time const& origin, const long from, const long to )
369{
370 update_( origin, from, to, false );
371}
372
373inline bool
374hh_psc_alpha_gap::wfr_update( Time const& origin, const long from, const long to )
375{
376 State_ old_state = S_; // save state before wfr_update
377 const bool wfr_tol_exceeded = update_( origin, from, to, true );
378 S_ = old_state; // restore old state
379
380 return not wfr_tol_exceeded;
381}
382
383inline size_t
384hh_psc_alpha_gap::send_test_event( Node& target, size_t receptor_type, synindex, bool )
385{
386 SpikeEvent se;
387 se.set_sender( *this );
388 return target.handles_test_event( se, receptor_type );
389}
390
391
392inline size_t
393hh_psc_alpha_gap::handles_test_event( SpikeEvent&, size_t receptor_type )
394{
395 if ( receptor_type != 0 )
396 {
397 throw UnknownReceptorType( receptor_type, get_name() );
398 }
399 return 0;
400}
401
402inline size_t
403hh_psc_alpha_gap::handles_test_event( CurrentEvent&, size_t receptor_type )
404{
405 if ( receptor_type != 0 )
406 {
407 throw UnknownReceptorType( receptor_type, get_name() );
408 }
409 return 0;
410}
411
412inline size_t
413hh_psc_alpha_gap::handles_test_event( DataLoggingRequest& dlr, size_t receptor_type )
414{
415 if ( receptor_type != 0 )
416 {
417 throw UnknownReceptorType( receptor_type, get_name() );
418 }
419 return B_.logger_.connect_logging_device( dlr, recordablesMap_ );
420}
421
422inline size_t
423hh_psc_alpha_gap::handles_test_event( GapJunctionEvent&, size_t receptor_type )
424{
425 if ( receptor_type != 0 )
426 {
427 throw UnknownReceptorType( receptor_type, get_name() );
428 }
429 return 0;
430}
431
432inline void
433hh_psc_alpha_gap::get_status( Dictionary& d ) const
434{
435 P_.get( d );
436 S_.get( d );
438
439 d[ names::recordables ] = recordablesMap_.get_list();
440}
441
442inline void
443hh_psc_alpha_gap::set_status( const Dictionary& d )
444{
445 Parameters_ ptmp = P_; // temporary copy in case of errors
446 ptmp.set( d, this ); // throws if BadProperty
447 State_ stmp = S_; // temporary copy in case of errors
448 stmp.set( d, this ); // throws if BadProperty
449
450 // We now know that (ptmp, stmp) are consistent. We do not
451 // write them back to (P_, S_) before we are also sure that
452 // the properties to be set in the parent class are internally
453 // consistent.
455
456 // if we get here, temporaries contain consistent set of properties
457 P_ = ptmp;
458 S_ = stmp;
459}
460
461} // namespace
462
463#endif // HAVE_GSL
464#endif // HH_PSC_ALPHA_GAP_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_Kv3("g_Kv3")
const std::string target("target")
const std::string g_Kv1("g_Kv1")
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
Declarations for base class Node.