NEST main@caf0ae8
 
Loading...
Searching...
No Matches
iaf_cond_alpha_mc.h
Go to the documentation of this file.
1/*
2 * iaf_cond_alpha_mc.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 IAF_COND_ALPHA_MC_H
24#define IAF_COND_ALPHA_MC_H
25
26// Generated includes:
27#include "config.h"
28
29#ifdef HAVE_GSL
30
31// C++ includes:
32#include <vector>
33
34// C includes:
35#include <gsl/gsl_errno.h>
36#include <gsl/gsl_matrix.h>
37#include <gsl/gsl_odeiv.h>
38
39// Includes from nestkernel:
40#include "archiving_node.h"
41#include "connection.h"
42#include "event.h"
43#include "nest_types.h"
44#include "recordables_map.h"
45#include "ring_buffer.h"
47
48
49namespace nest
50{
58extern "C" int iaf_cond_alpha_mc_dynamics( double, const double*, double*, void* );
59
60
61/* BeginUserDocs: neuron, integrate-and-fire, conductance-based, hard threshold
62
63Short description
64+++++++++++++++++
65
66Multi-compartment conductance-based leaky integrate-and-fire neuron model
67
68Description
69+++++++++++
70
71.. admonition:: Deprecated model
72
73 ``iaf_cond_alpha_mc`` is deprecated because ``cm_default`` is an improved
74 implementation of compartmental models in NEST (see :doc:`cm_default`).
75
76THIS MODEL IS A PROTOTYPE FOR ILLUSTRATION PURPOSES. IT IS NOT YET
77FULLY TESTED. USE AT YOUR OWN PERIL!
78
79``iaf_cond_alpha_mc`` is an implementation of a multi-compartment spiking
80neuron using IAF dynamics with conductance-based synapses. It serves
81mainly to illustrate the implementation of :ref:`multicompartment models
82<multicompartment-models>` in NEST.
83
84The model has three compartments: soma, proximal and distal dendrite,
85labeled as s, p, and d, respectively. Compartments are connected through
86passive conductances as follows
87
88.. math::
89
90 C_{m.s} d/dt V_{m.s} = \ldots - g_{sp} ( V_{m.s} - V_{m.p} ) \\
91
92 C_{m.p} d/dt V_{m.p} = \ldots - g_{sp} ( V_{m.p} - V_{m.s} )
93 - g_{pd} ( V_{m.p} - V_{m.d} ) \\
94
95 C_{m.d} d/dt V_{m.d} = \ldots \qquad - g_{pd} ( V_{m.d} - V_{m.p} )
96
97A spike is fired when the somatic membrane potential exceeds threshold,
98:math:`V_{m.s} >= V_{th}`. After a spike, somatic membrane potential is
99clamped to a reset potential, :math:` V_{m.s} == V_{reset}`, for the refractory
100period. Dendritic membrane potentials are not manipulated after a spike.
101
102There is one excitatory and one inhibitory conductance-based synapse
103onto each compartment, with alpha-function time course. The alpha
104function is normalized such that an event of weight 1.0 results in a
105peak current of 1 nS at :math:`t = \tau_{syn}`. Each compartment can also
106receive current input from a current generator, and an external (rheobase)
107current can be set for each compartment.
108
109Synapses, including those for injection external currents, are addressed through
110the receptor types given in the ``receptor_types`` entry of the state Dictionary.
111Note that in contrast to the single-compartment ``iaf_cond_alpha`` model, all
112synaptic weights must be positive numbers!
113
114See also :footcite:p:`Meffin2004`, :footcite:p:`Bernander1991`.
115
116Parameters
117++++++++++
118
119The following parameters can be set in the status Dictionary. Parameters
120for each compartment are collected in a sub-Dictionary; these sub-dictionaries
121are called "soma", "proximal", and "distal", respectively. In the list below,
122these parameters are marked with an asterisk.
123
124============ ======= ==========================================================
125 V_m* mV Membrane potential
126 E_L* mV Leak reversal potential
127 C_m* pF Capacity of the membrane
128 E_ex* mV Excitatory reversal potential
129 E_in* mV Inhibitory reversal potential
130 g_L* nS Leak conductance
131 tau_syn_ex* ms Rise time of the excitatory synaptic alpha function
132 tau_syn_in* ms Rise time of the inhibitory synaptic alpha function
133 I_e* pA Constant input current
134 g_sp nS Conductance connecting soma and proximal dendrite
135 g_pd nS Conductance connecting proximal and distal dendrite
136 t_ref ms Duration of refractory period
137 V_th mV Spike threshold in mV
138 V_reset mV Reset potential of the membrane
139============ ======= ==========================================================
140
141Sends
142+++++
143
144SpikeEvent
145
146Receives
147++++++++
148
149SpikeEvent, CurrentEvent, DataLoggingRequest
150
151References
152++++++++++
153
154
155.. footbibliography::
156
157See also
158++++++++
159
160iaf_cond_alpha
161
162Examples using this model
163+++++++++++++++++++++++++
164
165.. listexamples:: iaf_cond_alpha_mc
166
167EndUserDocs */
168
169void register_iaf_cond_alpha_mc( const std::string& name );
170
171class iaf_cond_alpha_mc : public ArchivingNode
172{
173
174 // Boilerplate function declarations --------------------------------
175
176public:
177 iaf_cond_alpha_mc();
178 iaf_cond_alpha_mc( const iaf_cond_alpha_mc& );
179 ~iaf_cond_alpha_mc() override;
180
186 using Node::handle;
187 using Node::handles_test_event;
188
189 size_t send_test_event( Node&, size_t, synindex, bool ) override;
190
191 void handle( SpikeEvent& ) override;
192 void handle( CurrentEvent& ) override;
193 void handle( DataLoggingRequest& ) override;
194
195 size_t handles_test_event( SpikeEvent&, size_t ) override;
196 size_t handles_test_event( CurrentEvent&, size_t ) override;
197 size_t handles_test_event( DataLoggingRequest&, size_t ) override;
198
199 void get_status( Dictionary& ) const override;
200 void set_status( const Dictionary& ) override;
201
202private:
203 void init_buffers_() override;
204 void pre_run_hook() override;
205 void update( Time const&, const long, const long ) override;
206
207 // Enumerations and constants specifying structure and properties ----
208
210 enum Compartments_
211 {
212 SOMA = 0,
213 PROX,
214 DIST,
215 NCOMP
216 };
217
223 static const size_t MIN_SPIKE_RECEPTOR = 1;
224
228 enum SpikeSynapseTypes
229 {
230 SOMA_EXC = MIN_SPIKE_RECEPTOR,
231 SOMA_INH,
232 PROX_EXC,
233 PROX_INH,
234 DIST_EXC,
235 DIST_INH,
236 SUP_SPIKE_RECEPTOR
237 };
238
239 static const size_t NUM_SPIKE_RECEPTORS = SUP_SPIKE_RECEPTOR - MIN_SPIKE_RECEPTOR;
240
246 static const size_t MIN_CURR_RECEPTOR = SUP_SPIKE_RECEPTOR;
247
251 enum CurrentSynapseTypes
252 {
253 I_SOMA = MIN_CURR_RECEPTOR,
254 I_PROX,
255 I_DIST,
256 SUP_CURR_RECEPTOR
257 };
258
259 static const size_t NUM_CURR_RECEPTORS = SUP_CURR_RECEPTOR - MIN_CURR_RECEPTOR;
260
261 // Friends --------------------------------------------------------
262
263 friend int iaf_cond_alpha_mc_dynamics( double, const double*, double*, void* );
264
265 friend class RecordablesMap< iaf_cond_alpha_mc >;
266 friend class UniversalDataLogger< iaf_cond_alpha_mc >;
267
268
269 // Parameters ------------------------------------------------------
270
289 struct Parameters_
290 {
291 double V_th;
292 double V_reset;
293 double t_ref;
294 double g_conn[ NCOMP - 1 ];
296 double g_L[ NCOMP ];
297 double C_m[ NCOMP ];
298 double E_ex[ NCOMP ];
299 double E_in[ NCOMP ];
300 double E_L[ NCOMP ];
302 double tau_synE[ NCOMP ];
304 double tau_synI[ NCOMP ];
306 double I_e[ NCOMP ];
307
308 Parameters_();
309 Parameters_( const Parameters_& );
310 Parameters_& operator=( const Parameters_& );
311
312 void get( Dictionary& ) const;
313 void set( const Dictionary&, Node* node );
314 };
315
316
317 // State variables ------------------------------------------------------
318
323public:
324 struct State_
325 {
332 enum StateVecElems_
333 {
334 V_M = 0,
335 DG_EXC,
336 G_EXC,
337 DG_INH,
338 G_INH,
339 STATE_VEC_COMPS
340 };
341
343 static const size_t STATE_VEC_SIZE = to_underlying( STATE_VEC_COMPS ) * to_underlying( NCOMP );
344
346 double y_[ STATE_VEC_SIZE ];
347 int r_;
348
349 State_( const Parameters_& );
350 State_( const State_& );
351
352 State_& operator=( const State_& );
353
354 void get( Dictionary& ) const;
355 void set( const Dictionary&, const Parameters_&, Node* );
356
364 static size_t
365 idx( size_t comp, StateVecElems_ elem )
366 {
367 return comp * STATE_VEC_COMPS + elem;
368 }
369 };
370
371private:
372 // Internal buffers --------------------------------------------------------
373
377 struct Buffers_
378 {
379 Buffers_( iaf_cond_alpha_mc& );
381 Buffers_( const Buffers_&, iaf_cond_alpha_mc& );
382
384 UniversalDataLogger< iaf_cond_alpha_mc > logger_;
385
389 std::vector< RingBuffer > spikes_;
390 std::vector< RingBuffer > currents_;
391
393 gsl_odeiv_step* s_;
394 gsl_odeiv_control* c_;
395 gsl_odeiv_evolve* e_;
396 gsl_odeiv_system sys_;
397
398 // Since IntegrationStep_ is initialized with step_, and the resolution
399 // cannot change after nodes have been created, it is safe to place both
400 // here.
401 double step_;
402 double IntegrationStep_;
403
411 double I_stim_[ NCOMP ];
412 };
413
414 // Internal variables ---------------------------------------------
415
419 struct Variables_
420 {
422 double PSConInit_E_[ NCOMP ];
423
425 double PSConInit_I_[ NCOMP ];
426
427 int RefractoryCounts_;
428 };
429
430 // Access functions for UniversalDataLogger -------------------------------
431
436 template < State_::StateVecElems_ elem, Compartments_ comp >
437 double
438 get_y_elem_() const
439 {
440 return S_.y_[ S_.idx( comp, elem ) ];
441 }
442
444 double
445 get_r_() const
446 {
447 return Time::get_resolution().get_ms() * S_.r_;
448 }
449
450 // Data members ----------------------------------------------------
451
452 Parameters_ P_;
453 State_ S_;
454 Variables_ V_;
455 Buffers_ B_;
456
458 static std::vector< std::string > comp_names_;
459
460 // Dictionary of receptor types, leads to seg fault on exit, see #328
461
463 static RecordablesMap< iaf_cond_alpha_mc > recordablesMap_;
464};
465
466inline size_t
467iaf_cond_alpha_mc::send_test_event( Node& target, size_t receptor_type, synindex, bool )
468{
469 SpikeEvent e;
470 e.set_sender( *this );
471 return target.handles_test_event( e, receptor_type );
472}
473
474inline size_t
475iaf_cond_alpha_mc::handles_test_event( SpikeEvent&, size_t receptor_type )
476{
477 if ( receptor_type < MIN_SPIKE_RECEPTOR or receptor_type >= SUP_SPIKE_RECEPTOR )
478 {
479 if ( receptor_type >= SUP_CURR_RECEPTOR )
480 {
481 throw UnknownReceptorType( receptor_type, get_name() );
482 }
483 else
484 {
485 throw IncompatibleReceptorType( receptor_type, get_name(), "SpikeEvent" );
486 }
487 }
488 return receptor_type - MIN_SPIKE_RECEPTOR;
489}
490
491inline size_t
492iaf_cond_alpha_mc::handles_test_event( CurrentEvent&, size_t receptor_type )
493{
494 if ( receptor_type < MIN_CURR_RECEPTOR or receptor_type >= SUP_CURR_RECEPTOR )
495 {
496 if ( receptor_type < MIN_CURR_RECEPTOR )
497 {
498 throw IncompatibleReceptorType( receptor_type, get_name(), "CurrentEvent" );
499 }
500 else
501 {
502 throw UnknownReceptorType( receptor_type, get_name() );
503 }
504 }
505 return receptor_type - MIN_CURR_RECEPTOR;
506}
507
508inline size_t
509iaf_cond_alpha_mc::handles_test_event( DataLoggingRequest& dlr, size_t receptor_type )
510{
511 if ( receptor_type != 0 )
512 {
513 if ( receptor_type >= SUP_CURR_RECEPTOR )
514 {
515 throw UnknownReceptorType( receptor_type, get_name() );
516 }
517 else
518 {
519 throw IncompatibleReceptorType( receptor_type, get_name(), "DataLoggingRequest" );
520 }
521 }
522 return B_.logger_.connect_logging_device( dlr, recordablesMap_ );
523}
524
525inline void
526iaf_cond_alpha_mc::get_status( Dictionary& d ) const
527{
528 P_.get( d );
529 S_.get( d );
531
532 d[ names::recordables ] = recordablesMap_.get_list();
533
539 Dictionary receptor_dict_;
540 receptor_dict_[ names::soma_exc ] = static_cast< long >( SOMA_EXC );
541 receptor_dict_[ names::soma_inh ] = static_cast< long >( SOMA_INH );
542 receptor_dict_[ names::soma_curr ] = static_cast< long >( I_SOMA );
543
544 receptor_dict_[ names::proximal_exc ] = static_cast< long >( PROX_EXC );
545 receptor_dict_[ names::proximal_inh ] = static_cast< long >( PROX_INH );
546 receptor_dict_[ names::proximal_curr ] = static_cast< long >( I_PROX );
547
548 receptor_dict_[ names::distal_exc ] = static_cast< long >( DIST_EXC );
549 receptor_dict_[ names::distal_inh ] = static_cast< long >( DIST_INH );
550 receptor_dict_[ names::distal_curr ] = static_cast< long >( I_DIST );
551
552 d[ names::receptor_types ] = receptor_dict_;
553}
554
555inline void
556iaf_cond_alpha_mc::set_status( const Dictionary& d )
557{
558 Parameters_ ptmp = P_; // temporary copy in case of errors
559 ptmp.set( d, this ); // throws if BadProperty
560 State_ stmp = S_; // temporary copy in case of errors
561 stmp.set( d, ptmp, this ); // throws if BadProperty
562
563 // We now know that (ptmp, stmp) are consistent. We do not
564 // write them back to (P_, S_) before we are also sure that
565 // the properties to be set in the parent class are internally
566 // consistent.
568
569 // if we get here, temporaries contain consistent set of properties
570 P_ = ptmp;
571 S_ = stmp;
572}
573
574} // namespace
575
576#endif // HAVE_GSL
577
578#endif // IAF_COND_ALPHA_MC_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 t_ref("t_ref")
const std::string E_L("E_L")
const std::string I_e("I_e")
const std::string V_reset("V_reset")
const std::string recordables("recordables")
const std::string C_m("C_m")
const std::string d("d")
const std::string V_th("V_th")
const std::string receptor_types("receptor_types")
const std::string proximal_curr("proximal_curr")
const std::string receptor_type("receptor_type")
const std::string E_in("E_in")
const std::string soma_exc("soma_exc")
const std::string distal_inh("distal_inh")
const std::string target("target")
const std::string distal_curr("distal_curr")
const std::string proximal_inh("proximal_inh")
const std::string soma_curr("soma_curr")
const std::string distal_exc("distal_exc")
const std::string E_ex("E_ex")
const std::string proximal_exc("proximal_exc")
const std::string soma_inh("soma_inh")
const std::string g_L("g_L")
Namespace for the NEST simulation kernel.
Definition beta_normalization_factor.h:33
constexpr auto to_underlying(E e) noexcept
Cast enum value to underlying integer type.
Definition nest_types.h:182
size_t synindex
For enumerations of synapse types.
Definition nest_types.h:115
const double e
Definition numerics.cpp:32