/**
* hhca_psc_alpha.h
*
* This file is part of NEST.
*
* Copyright (C) 2004 The NEST Initiative
*
* NEST is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* NEST is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NEST. If not, see <http://www.gnu.org/licenses/>.
*
* Generated from NESTML at time: 2021-09-17 08:49:06.519180
**/#ifndef HHCA_PSC_ALPHA#define HHCA_PSC_ALPHA#include"config.h"#ifndef HAVE_GSL#error"The GSL library is required for neurons that require a numerical solver."#endif// External includes:#include<gsl/gsl_errno.h>#include<gsl/gsl_matrix.h>#include<gsl/gsl_odeiv.h>// Includes from nestkernel:#include"archiving_node.h"#include"connection.h"#include"event.h"#include"nest_types.h"#include"ring_buffer.h"#include"universal_data_logger.h"// Includes from sli:#include"dictdatum.h"/**
* Function computing right-hand side of ODE for GSL solver.
* @note Must be declared here so we can befriend it in class.
* @note Must have C-linkage for passing to GSL. Internally, it is
* a first-class C++ function, but cannot be a member function
* because of the C-linkage.
* @note No point in declaring it inline, since it is called
* through a function pointer.
* @param void* Pointer to model neuron instance.
**/extern"C"inlineinthhca_psc_alpha_dynamics( double, constdouble y[], double f[], void* pnode );
/* BeginDocumentation
Name: hhca_psc_alpha.
Description:
"""
Name: hhca_psc_alpha - Hodgkin Huxley neuron model.
Description:
hhca_psc_alpha is an implementation of a spiking neuron using the Hodkin-Huxley
formalism.
(1) Post-syaptic currents
Incoming spike events induce a post-synaptic change of current modelled
by an alpha function. The alpha function is normalised such that an event of
weight 1.0 results in a peak current of 1 pA.
(2) Spike Detection
Spike detection is done by a combined threshold-and-local-maximum search: if
there is a local maximum above a certain threshold of the membrane potential,
it is considered a spike.
Problems/Todo:
better spike detection
initial wavelet/spike at simulation onset
References:
Spiking Neuron Models:
Single Neurons, Populations, Plasticity
Wulfram Gerstner, Werner Kistler, Cambridge University Press
Theoretical Neuroscience:
Computational and Mathematical Modeling of Neural Systems
Peter Dayan, L. F. Abbott, MIT Press (parameters taken from here)
Hodgkin, A. L. and Huxley, A. F.,
A Quantitative Description of Membrane Current
and Its Application to Conduction and Excitation in Nerve,
Journal of Physiology, 117, 500-544 (1952)
Sends: SpikeEvent
Receives: SpikeEvent, CurrentEvent, DataLoggingRequest
Authors: Tanguy Fardet
SeeAlso: hh_psc_alpha
"""
Parameters:
The following parameters can be set in the status dictionary.
t_ref [ms] Refractory period
g_Na [nS] Sodium peak conductance
g_K [nS] Potassium peak conductance
g_L [nS] Leak conductance
C_m [pF] Membrane Capacitance
E_Na [mV] Sodium reversal potential
E_K [mV] Potassium reversal potential
E_L [mV] Leak reversal Potential (aka resting potential)
tau_syn_ex [ms] Rise time of the excitatory synaptic alpha function i
tau_syn_in [ms] Rise time of the inhibitory synaptic alpha function
I_e [pA] constant external input current
Dynamic state variables:
r [integer] number of steps in the current refractory phase
V_m [mV] Membrane potential
Act_m [real] Activation variable m for Na
Inact_h [real] Inactivation variable h for Na
Act_n [real] Activation variable n for K
Sends: nest::SpikeEvent
Receives: Spike, Current, DataLoggingRequest
*/classhhca_psc_alpha : public nest::ArchivingNode
{
public:
/**
* The constructor is only used to create the model prototype in the model manager.
**/
hhca_psc_alpha();
/**
* The copy constructor is used to create model copies and instances of the model.
* @node The copy constructor needs to initialize the parameters and the state.
* Initialization of buffers and interal variables is deferred to
* @c init_buffers_() and @c calibrate().
**/
hhca_psc_alpha(const hhca_psc_alpha &);
/**
* Destructor.
**/
~hhca_psc_alpha();
// -------------------------------------------------------------------------// Import sets of overloaded virtual functions.// See: Technical Issues / Virtual Functions: Overriding, Overloading,// and Hiding// -------------------------------------------------------------------------
using nest::Node::handles_test_event;
using nest::Node::handle;
/**
* Used to validate that we can send nest::SpikeEvent to desired target:port.
**/
nest::port send_test_event(nest::Node& target, nest::rport receptor_type, nest::synindex, bool);
// -------------------------------------------------------------------------// Functions handling incoming events.// We tell nest that we can handle incoming events of various types by// defining handle() for the given event.// -------------------------------------------------------------------------voidhandle(nest::SpikeEvent &); //! accept spikesvoidhandle(nest::CurrentEvent &); //! accept input currentvoidhandle(nest::DataLoggingRequest &);//! allow recording with multimeter
nest::port handles_test_event(nest::SpikeEvent&, nest::port);
nest::port handles_test_event(nest::CurrentEvent&, nest::port);
nest::port handles_test_event(nest::DataLoggingRequest&, nest::port);
// -------------------------------------------------------------------------// Functions for getting/setting parameters and state values.// -------------------------------------------------------------------------voidget_status(DictionaryDatum &)const;
voidset_status(const DictionaryDatum &);
private:
/**
* Reset internal buffers of neuron.
**/voidinit_buffers_();
/**
* Initialize auxiliary quantities, leave parameters and state untouched.
**/voidcalibrate();
/**
* Take neuron through given time interval
**/voidupdate(nest::Time const &, constlong, constlong);
// The next two classes need to be friends to access the State_ class/member
friend classnest::RecordablesMap<hhca_psc_alpha>;
friend classnest::UniversalDataLogger<hhca_psc_alpha>;
/**
* Free parameters of the neuron.
*
*
*
* These are the parameters that can be set by the user through @c `node.set()`.
* They are initialized from the model prototype when the node is created.
* Parameters do not change during calls to @c update() and are not reset by
* @c ResetNetwork.
*
* @note Parameters_ need neither copy constructor nor @c operator=(), since
* all its members are copied properly by the default copy constructor
* and assignment operator. Important:
* - If Parameters_ contained @c Time members, you need to define the
* assignment operator to recalibrate all members of type @c Time . You
* may also want to define the assignment operator.
* - If Parameters_ contained members that cannot copy themselves, such
* as C-style arrays, you need to define the copy constructor and
* assignment operator to copy those members.
**/structParameters_
{//! Refractory perioddouble t_ref;
//! Sodium peak conductancedouble g_Na;
//! Potassium peak conductancedouble g_K;
//! Leak conductancedouble g_L;
//! Membrane Capacitancedouble C_m;
//! Sodium reversal potentialdouble E_Na;
//! Potassium reversal potentialdouble E_K;
//! Leak reversal Potential (aka resting potential)double E_L;
//! Rise time of the excitatory synaptic alpha function idouble tau_syn_ex;
//! Rise time of the inhibitory synaptic alpha functiondouble tau_syn_in;
double g_Ca;
double Ca_env;
double Ca_i_eq;
double tau_Ca;
double V_hmCa;
double k_mCa;
double tau_mCa;
double V_hhCa;
double k_hCa;
double tau_hCa;
double g_AHP;
double K_AHP;
double b_AHP;
double tau_AHP;
double E_0;
double Vcell;
//! constant external input currentdouble I_e;
double __gsl_error_tol;
/**
* Initialize parameters to their default values.
**/
Parameters_();
};
/**
* Dynamic state of the neuron.
*
*
*
* These are the state variables that are advanced in time by calls to
* @c update(). In many models, some or all of them can be set by the user
* through @c `node.set()`. The state variables are initialized from the model
* prototype when the node is created. State variables are reset by @c ResetNetwork.
*
* @note State_ need neither copy constructor nor @c operator=(), since
* all its members are copied properly by the default copy constructor
* and assignment operator. Important:
* - If State_ contained @c Time members, you need to define the
* assignment operator to recalibrate all members of type @c Time . You
* may also want to define the assignment operator.
* - If State_ contained members that cannot copy themselves, such
* as C-style arrays, you need to define the copy constructor and
* assignment operator to copy those members.
**/structState_
{//! Symbolic indices to the elements of the state vector yenumStateVecElems
{
V_m,
Ca_i,
Act_n,
Act_m,
Inact_h,
h_Ca,
m_Ca,
m_AHP,
I_syn_ex__X__spikeExc,
I_syn_ex__X__spikeExc__d,
I_syn_in__X__spikeInh,
I_syn_in__X__spikeInh__d,
r,
alpha_n_init,
beta_n_init,
alpha_m_init,
beta_m_init,
alpha_h_init,
beta_h_init,
STATE_VEC_SIZE
};
//! state vector, must be C-array for GSL solverdouble ode_state[STATE_VEC_SIZE];
State_();
};
/**
* Internal variables of the neuron.
*
*
*
* These variables must be initialized by @c calibrate, which is called before
* the first call to @c update() upon each call to @c Simulate.
* @node Variables_ needs neither constructor, copy constructor or assignment operator,
* since it is initialized by @c calibrate(). If Variables_ has members that
* cannot destroy themselves, Variables_ will need a destructor.
**/structVariables_
{//! refractory time in stepslong RefractoryCounts;
double __h;
double charge;
double avogadro;
//! convert charge flux to concentration roughly 1e-2 mmol/L/fCdouble c2c;
double __P__I_syn_ex__X__spikeExc__I_syn_ex__X__spikeExc;
double __P__I_syn_ex__X__spikeExc__I_syn_ex__X__spikeExc__d;
double __P__I_syn_ex__X__spikeExc__d__I_syn_ex__X__spikeExc;
double __P__I_syn_ex__X__spikeExc__d__I_syn_ex__X__spikeExc__d;
double __P__I_syn_in__X__spikeInh__I_syn_in__X__spikeInh;
double __P__I_syn_in__X__spikeInh__I_syn_in__X__spikeInh__d;
double __P__I_syn_in__X__spikeInh__d__I_syn_in__X__spikeInh;
double __P__I_syn_in__X__spikeInh__d__I_syn_in__X__spikeInh__d;
};
/**
* Buffers of the neuron.
* Usually buffers for incoming spikes and data logged for analog recorders.
* Buffers must be initialized by @c init_buffers_(), which is called before
* @c calibrate() on the first call to @c Simulate after the start of NEST,
* ResetKernel or ResetNetwork.
* @node Buffers_ needs neither constructor, copy constructor or assignment operator,
* since it is initialized by @c init_nodes_(). If Buffers_ has members that
* cannot destroy themselves, Buffers_ will need a destructor.
**/structBuffers_
{
Buffers_(hhca_psc_alpha &);
Buffers_(const Buffers_ &, hhca_psc_alpha &);
/**
* Logger for all analog data
**/
nest::UniversalDataLogger<hhca_psc_alpha> logger_;
inline nest::RingBuffer& get_spikeInh() {return spikeInh;}
//!< Buffer for input (type: pA)
nest::RingBuffer spikeInh;
double spikeInh_grid_sum_;
inline nest::RingBuffer& get_spikeExc() {return spikeExc;}
//!< Buffer for input (type: pA)
nest::RingBuffer spikeExc;
double spikeExc_grid_sum_;
//!< Buffer for input (type: pA)
nest::RingBuffer I_stim;
inline nest::RingBuffer& get_I_stim() {return I_stim;}
double I_stim_grid_sum_;
// -----------------------------------------------------------------------// GSL ODE solver data structures// -----------------------------------------------------------------------
gsl_odeiv_step* __s; //!< stepping function
gsl_odeiv_control* __c; //!< adaptive stepsize control function
gsl_odeiv_evolve* __e; //!< evolution function
gsl_odeiv_system __sys; //!< struct describing system// __integration_step should be reset with the neuron on ResetNetwork,// but remain unchanged during calibration. Since it is initialized with// step_, and the resolution cannot change after nodes have been created,// it is safe to place both here.double __step; //!< step size in msdouble __integration_step; //!< current integration time step, updated by GSL
};
// -------------------------------------------------------------------------// Getters/setters for state block// -------------------------------------------------------------------------inlinelongget_r()const
{
return S_.ode_state[State_::r];
}
inlinevoidset_r(constlong __v)
{
S_.ode_state[State_::r] = __v;
}
inlinedoubleget_V_m()const
{
return S_.ode_state[State_::V_m];
}
inlinevoidset_V_m(constdouble __v)
{
S_.ode_state[State_::V_m] = __v;
}
inlinedoubleget_Ca_i()const
{
return S_.ode_state[State_::Ca_i];
}
inlinevoidset_Ca_i(constdouble __v)
{
S_.ode_state[State_::Ca_i] = __v;
}
inlinedoubleget_alpha_n_init()const
{
return S_.ode_state[State_::alpha_n_init];
}
inlinevoidset_alpha_n_init(constdouble __v)
{
S_.ode_state[State_::alpha_n_init] = __v;
}
inlinedoubleget_beta_n_init()const
{
return S_.ode_state[State_::beta_n_init];
}
inlinevoidset_beta_n_init(constdouble __v)
{
S_.ode_state[State_::beta_n_init] = __v;
}
inlinedoubleget_alpha_m_init()const
{
return S_.ode_state[State_::alpha_m_init];
}
inlinevoidset_alpha_m_init(constdouble __v)
{
S_.ode_state[State_::alpha_m_init] = __v;
}
inlinedoubleget_beta_m_init()const
{
return S_.ode_state[State_::beta_m_init];
}
inlinevoidset_beta_m_init(constdouble __v)
{
S_.ode_state[State_::beta_m_init] = __v;
}
inlinedoubleget_alpha_h_init()const
{
return S_.ode_state[State_::alpha_h_init];
}
inlinevoidset_alpha_h_init(constdouble __v)
{
S_.ode_state[State_::alpha_h_init] = __v;
}
inlinedoubleget_beta_h_init()const
{
return S_.ode_state[State_::beta_h_init];
}
inlinevoidset_beta_h_init(constdouble __v)
{
S_.ode_state[State_::beta_h_init] = __v;
}
inlinedoubleget_Act_m()const
{
return S_.ode_state[State_::Act_m];
}
inlinevoidset_Act_m(constdouble __v)
{
S_.ode_state[State_::Act_m] = __v;
}
inlinedoubleget_Inact_h()const
{
return S_.ode_state[State_::Inact_h];
}
inlinevoidset_Inact_h(constdouble __v)
{
S_.ode_state[State_::Inact_h] = __v;
}
inlinedoubleget_Act_n()const
{
return S_.ode_state[State_::Act_n];
}
inlinevoidset_Act_n(constdouble __v)
{
S_.ode_state[State_::Act_n] = __v;
}
inlinedoubleget_h_Ca()const
{
return S_.ode_state[State_::h_Ca];
}
inlinevoidset_h_Ca(constdouble __v)
{
S_.ode_state[State_::h_Ca] = __v;
}
inlinedoubleget_m_Ca()const
{
return S_.ode_state[State_::m_Ca];
}
inlinevoidset_m_Ca(constdouble __v)
{
S_.ode_state[State_::m_Ca] = __v;
}
inlinedoubleget_m_AHP()const
{
return S_.ode_state[State_::m_AHP];
}
inlinevoidset_m_AHP(constdouble __v)
{
S_.ode_state[State_::m_AHP] = __v;
}
inlinedoubleget_I_syn_ex__X__spikeExc()const
{
return S_.ode_state[State_::I_syn_ex__X__spikeExc];
}
inlinevoidset_I_syn_ex__X__spikeExc(constdouble __v)
{
S_.ode_state[State_::I_syn_ex__X__spikeExc] = __v;
}
inlinedoubleget_I_syn_ex__X__spikeExc__d()const
{
return S_.ode_state[State_::I_syn_ex__X__spikeExc__d];
}
inlinevoidset_I_syn_ex__X__spikeExc__d(constdouble __v)
{
S_.ode_state[State_::I_syn_ex__X__spikeExc__d] = __v;
}
inlinedoubleget_I_syn_in__X__spikeInh()const
{
return S_.ode_state[State_::I_syn_in__X__spikeInh];
}
inlinevoidset_I_syn_in__X__spikeInh(constdouble __v)
{
S_.ode_state[State_::I_syn_in__X__spikeInh] = __v;
}
inlinedoubleget_I_syn_in__X__spikeInh__d()const
{
return S_.ode_state[State_::I_syn_in__X__spikeInh__d];
}
inlinevoidset_I_syn_in__X__spikeInh__d(constdouble __v)
{
S_.ode_state[State_::I_syn_in__X__spikeInh__d] = __v;
}
// -------------------------------------------------------------------------// Getters/setters for parameters// -------------------------------------------------------------------------inlinedoubleget_t_ref()const
{
return P_.t_ref;
}
inlinevoidset_t_ref(constdouble __v)
{
P_.t_ref = __v;
}
inlinedoubleget_g_Na()const
{
return P_.g_Na;
}
inlinevoidset_g_Na(constdouble __v)
{
P_.g_Na = __v;
}
inlinedoubleget_g_K()const
{
return P_.g_K;
}
inlinevoidset_g_K(constdouble __v)
{
P_.g_K = __v;
}
inlinedoubleget_g_L()const
{
return P_.g_L;
}
inlinevoidset_g_L(constdouble __v)
{
P_.g_L = __v;
}
inlinedoubleget_C_m()const
{
return P_.C_m;
}
inlinevoidset_C_m(constdouble __v)
{
P_.C_m = __v;
}
inlinedoubleget_E_Na()const
{
return P_.E_Na;
}
inlinevoidset_E_Na(constdouble __v)
{
P_.E_Na = __v;
}
inlinedoubleget_E_K()const
{
return P_.E_K;
}
inlinevoidset_E_K(constdouble __v)
{
P_.E_K = __v;
}
inlinedoubleget_E_L()const
{
return P_.E_L;
}
inlinevoidset_E_L(constdouble __v)
{
P_.E_L = __v;
}
inlinedoubleget_tau_syn_ex()const
{
return P_.tau_syn_ex;
}
inlinevoidset_tau_syn_ex(constdouble __v)
{
P_.tau_syn_ex = __v;
}
inlinedoubleget_tau_syn_in()const
{
return P_.tau_syn_in;
}
inlinevoidset_tau_syn_in(constdouble __v)
{
P_.tau_syn_in = __v;
}
inlinedoubleget_g_Ca()const
{
return P_.g_Ca;
}
inlinevoidset_g_Ca(constdouble __v)
{
P_.g_Ca = __v;
}
inlinedoubleget_Ca_env()const
{
return P_.Ca_env;
}
inlinevoidset_Ca_env(constdouble __v)
{
P_.Ca_env = __v;
}
inlinedoubleget_Ca_i_eq()const
{
return P_.Ca_i_eq;
}
inlinevoidset_Ca_i_eq(constdouble __v)
{
P_.Ca_i_eq = __v;
}
inlinedoubleget_tau_Ca()const
{
return P_.tau_Ca;
}
inlinevoidset_tau_Ca(constdouble __v)
{
P_.tau_Ca = __v;
}
inlinedoubleget_V_hmCa()const
{
return P_.V_hmCa;
}
inlinevoidset_V_hmCa(constdouble __v)
{
P_.V_hmCa = __v;
}
inlinedoubleget_k_mCa()const
{
return P_.k_mCa;
}
inlinevoidset_k_mCa(constdouble __v)
{
P_.k_mCa = __v;
}
inlinedoubleget_tau_mCa()const
{
return P_.tau_mCa;
}
inlinevoidset_tau_mCa(constdouble __v)
{
P_.tau_mCa = __v;
}
inlinedoubleget_V_hhCa()const
{
return P_.V_hhCa;
}
inlinevoidset_V_hhCa(constdouble __v)
{
P_.V_hhCa = __v;
}
inlinedoubleget_k_hCa()const
{
return P_.k_hCa;
}
inlinevoidset_k_hCa(constdouble __v)
{
P_.k_hCa = __v;
}
inlinedoubleget_tau_hCa()const
{
return P_.tau_hCa;
}
inlinevoidset_tau_hCa(constdouble __v)
{
P_.tau_hCa = __v;
}
inlinedoubleget_g_AHP()const
{
return P_.g_AHP;
}
inlinevoidset_g_AHP(constdouble __v)
{
P_.g_AHP = __v;
}
inlinedoubleget_K_AHP()const
{
return P_.K_AHP;
}
inlinevoidset_K_AHP(constdouble __v)
{
P_.K_AHP = __v;
}
inlinedoubleget_b_AHP()const
{
return P_.b_AHP;
}
inlinevoidset_b_AHP(constdouble __v)
{
P_.b_AHP = __v;
}
inlinedoubleget_tau_AHP()const
{
return P_.tau_AHP;
}
inlinevoidset_tau_AHP(constdouble __v)
{
P_.tau_AHP = __v;
}
inlinedoubleget_E_0()const
{
return P_.E_0;
}
inlinevoidset_E_0(constdouble __v)
{
P_.E_0 = __v;
}
inlinedoubleget_Vcell()const
{
return P_.Vcell;
}
inlinevoidset_Vcell(constdouble __v)
{
P_.Vcell = __v;
}
inlinedoubleget_I_e()const
{
return P_.I_e;
}
inlinevoidset_I_e(constdouble __v)
{
P_.I_e = __v;
}
// -------------------------------------------------------------------------// Getters/setters for internals// -------------------------------------------------------------------------inlinelongget_RefractoryCounts()const
{
return V_.RefractoryCounts;
}
inlinevoidset_RefractoryCounts(constlong __v)
{
V_.RefractoryCounts = __v;
}
inlinedoubleget___h()const
{
return V_.__h;
}
inlinevoidset___h(constdouble __v)
{
V_.__h = __v;
}
inlinedoubleget_charge()const
{
return V_.charge;
}
inlinevoidset_charge(constdouble __v)
{
V_.charge = __v;
}
inlinedoubleget_avogadro()const
{
return V_.avogadro;
}
inlinevoidset_avogadro(constdouble __v)
{
V_.avogadro = __v;
}
inlinedoubleget_c2c()const
{
return V_.c2c;
}
inlinevoidset_c2c(constdouble __v)
{
V_.c2c = __v;
}
inlinedoubleget___P__I_syn_ex__X__spikeExc__I_syn_ex__X__spikeExc()const
{
return V_.__P__I_syn_ex__X__spikeExc__I_syn_ex__X__spikeExc;
}
inlinevoidset___P__I_syn_ex__X__spikeExc__I_syn_ex__X__spikeExc(constdouble __v)
{
V_.__P__I_syn_ex__X__spikeExc__I_syn_ex__X__spikeExc = __v;
}
inlinedoubleget___P__I_syn_ex__X__spikeExc__I_syn_ex__X__spikeExc__d()const
{
return V_.__P__I_syn_ex__X__spikeExc__I_syn_ex__X__spikeExc__d;
}
inlinevoidset___P__I_syn_ex__X__spikeExc__I_syn_ex__X__spikeExc__d(constdouble __v)
{
V_.__P__I_syn_ex__X__spikeExc__I_syn_ex__X__spikeExc__d = __v;
}
inlinedoubleget___P__I_syn_ex__X__spikeExc__d__I_syn_ex__X__spikeExc()const
{
return V_.__P__I_syn_ex__X__spikeExc__d__I_syn_ex__X__spikeExc;
}
inlinevoidset___P__I_syn_ex__X__spikeExc__d__I_syn_ex__X__spikeExc(constdouble __v)
{
V_.__P__I_syn_ex__X__spikeExc__d__I_syn_ex__X__spikeExc = __v;
}
inlinedoubleget___P__I_syn_ex__X__spikeExc__d__I_syn_ex__X__spikeExc__d()const
{
return V_.__P__I_syn_ex__X__spikeExc__d__I_syn_ex__X__spikeExc__d;
}
inlinevoidset___P__I_syn_ex__X__spikeExc__d__I_syn_ex__X__spikeExc__d(constdouble __v)
{
V_.__P__I_syn_ex__X__spikeExc__d__I_syn_ex__X__spikeExc__d = __v;
}
inlinedoubleget___P__I_syn_in__X__spikeInh__I_syn_in__X__spikeInh()const
{
return V_.__P__I_syn_in__X__spikeInh__I_syn_in__X__spikeInh;
}
inlinevoidset___P__I_syn_in__X__spikeInh__I_syn_in__X__spikeInh(constdouble __v)
{
V_.__P__I_syn_in__X__spikeInh__I_syn_in__X__spikeInh = __v;
}
inlinedoubleget___P__I_syn_in__X__spikeInh__I_syn_in__X__spikeInh__d()const
{
return V_.__P__I_syn_in__X__spikeInh__I_syn_in__X__spikeInh__d;
}
inlinevoidset___P__I_syn_in__X__spikeInh__I_syn_in__X__spikeInh__d(constdouble __v)
{
V_.__P__I_syn_in__X__spikeInh__I_syn_in__X__spikeInh__d = __v;
}
inlinedoubleget___P__I_syn_in__X__spikeInh__d__I_syn_in__X__spikeInh()const
{
return V_.__P__I_syn_in__X__spikeInh__d__I_syn_in__X__spikeInh;
}
inlinevoidset___P__I_syn_in__X__spikeInh__d__I_syn_in__X__spikeInh(constdouble __v)
{
V_.__P__I_syn_in__X__spikeInh__d__I_syn_in__X__spikeInh = __v;
}
inlinedoubleget___P__I_syn_in__X__spikeInh__d__I_syn_in__X__spikeInh__d()const
{
return V_.__P__I_syn_in__X__spikeInh__d__I_syn_in__X__spikeInh__d;
}
inlinevoidset___P__I_syn_in__X__spikeInh__d__I_syn_in__X__spikeInh__d(constdouble __v)
{
V_.__P__I_syn_in__X__spikeInh__d__I_syn_in__X__spikeInh__d = __v;
}
// -------------------------------------------------------------------------// Getters/setters for inline expressions// -------------------------------------------------------------------------inlinedoubleget_m_infAHP()const
{
returnpow((S_.ode_state[State_::Ca_i] / P_.K_AHP), 2) / (pow((S_.ode_state[State_::Ca_i] / P_.K_AHP), 2) + P_.b_AHP);
}
inlinedoubleget_m_infCa()const
{
return y_shape(S_.ode_state[State_::V_m], P_.V_hmCa, P_.k_mCa);
}
inlinedoubleget_h_infCa()const
{
return y_shape(S_.ode_state[State_::V_m], P_.V_hhCa, (-P_.k_hCa));
}
inlinedoubleget_E_Ca()const
{
return2 * P_.E_0 * std::log(P_.Ca_env / S_.ode_state[State_::Ca_i]);
}
inlinedoubleget_I_syn_exc()const
{
return S_.ode_state[State_::I_syn_ex__X__spikeExc];
}
inlinedoubleget_I_syn_inh()const
{
return S_.ode_state[State_::I_syn_in__X__spikeInh];
}
inlinedoubleget_I_Na()const
{
return P_.g_Na * S_.ode_state[State_::Act_m] * S_.ode_state[State_::Act_m] * S_.ode_state[State_::Act_m] * S_.ode_state[State_::Inact_h] * (S_.ode_state[State_::V_m] - P_.E_Na);
}
inlinedoubleget_I_K()const
{
return (P_.g_K * S_.ode_state[State_::Act_n] * S_.ode_state[State_::Act_n] * S_.ode_state[State_::Act_n] * S_.ode_state[State_::Act_n] + P_.g_AHP * pow(S_.ode_state[State_::m_AHP], 2)) * (S_.ode_state[State_::V_m] - P_.E_K);
}
inlinedoubleget_I_Ca()const
{
return (-P_.g_Ca) * S_.ode_state[State_::m_Ca] * S_.ode_state[State_::h_Ca] * (S_.ode_state[State_::V_m] - (2 * P_.E_0 * std::log(P_.Ca_env / S_.ode_state[State_::Ca_i])));
}
inlinedoubleget_I_L()const
{
return P_.g_L * (S_.ode_state[State_::V_m] - P_.E_L);
}
inlinedoubleget_alpha_n()const
{
return (0.01 * (S_.ode_state[State_::V_m] / 1.0 + 55.0)) / (1.0 - std::exp((-(S_.ode_state[State_::V_m] / 1.0 + 55.0)) / 10.0));
}
inlinedoubleget_beta_n()const
{
return0.125 * std::exp((-(S_.ode_state[State_::V_m] / 1.0 + 65.0)) / 80.0);
}
inlinedoubleget_alpha_m()const
{
return (0.1 * (S_.ode_state[State_::V_m] / 1.0 + 40.0)) / (1.0 - std::exp((-(S_.ode_state[State_::V_m] / 1.0 + 40.0)) / 10.0));
}
inlinedoubleget_beta_m()const
{
return4.0 * std::exp((-(S_.ode_state[State_::V_m] / 1.0 + 65.0)) / 18.0);
}
inlinedoubleget_alpha_h()const
{
return0.07 * std::exp((-(S_.ode_state[State_::V_m] / 1.0 + 65.0)) / 20.0);
}
inlinedoubleget_beta_h()const
{
return1.0 / (1.0 + std::exp((-(S_.ode_state[State_::V_m] / 1.0 + 35.0)) / 10.0));
}
// -------------------------------------------------------------------------// Getters/setters for input buffers// -------------------------------------------------------------------------inline nest::RingBuffer& get_spikeInh() {return B_.get_spikeInh();};
inline nest::RingBuffer& get_spikeExc() {return B_.get_spikeExc();};
inline nest::RingBuffer& get_I_stim() {return B_.get_I_stim();};
// -------------------------------------------------------------------------// Function declarations// -------------------------------------------------------------------------//doubley_shape(double, double, double)const
;
// -------------------------------------------------------------------------// Member variables of neuron model.// Each model neuron should have precisely the following four data members,// which are one instance each of the parameters, state, buffers and variables// structures. Experience indicates that the state and variables member should// be next to each other to achieve good efficiency (caching).// Note: Devices require one additional data member, an instance of the // ``Device`` child class they belong to.// -------------------------------------------------------------------------
Parameters_ P_; //!< Free parameters.
State_ S_; //!< Dynamic state.
Variables_ V_; //!< Internal Variables
Buffers_ B_; //!< Buffers.//! Mapping of recordables names to access functionsstatic nest::RecordablesMap<hhca_psc_alpha> recordablesMap_;
friend inthhca_psc_alpha_dynamics( double, constdouble y[], double f[], void* pnode );
}; /* neuron hhca_psc_alpha */inline nest::port hhca_psc_alpha::send_test_event(nest::Node& target, nest::rport receptor_type, nest::synindex, bool)
{
// You should usually not change the code in this function.// It confirms that the target of connection @c c accepts @c nest::SpikeEvent on// the given @c receptor_type.
nest::SpikeEvent e;
e.set_sender(*this);
return target.handles_test_event(e, receptor_type);
}
inline nest::port hhca_psc_alpha::handles_test_event(nest::SpikeEvent&, nest::port receptor_type)
{
// You should usually not change the code in this function.// It confirms to the connection management system that we are able// to handle @c SpikeEvent on port 0. You need to extend the function// if you want to differentiate between input ports.if (receptor_type != 0)
{
throw nest::UnknownReceptorType(receptor_type, get_name());
}
return0;
}
inline nest::port hhca_psc_alpha::handles_test_event(nest::CurrentEvent&, nest::port receptor_type)
{
// You should usually not change the code in this function.// It confirms to the connection management system that we are able// to handle @c CurrentEvent on port 0. You need to extend the function// if you want to differentiate between input ports.if (receptor_type != 0)
{
throw nest::UnknownReceptorType(receptor_type, get_name());
}
return0;
}
inline nest::port hhca_psc_alpha::handles_test_event(nest::DataLoggingRequest& dlr, nest::port receptor_type)
{
// You should usually not change the code in this function.// It confirms to the connection management system that we are able// to handle @c DataLoggingRequest on port 0.// The function also tells the built-in UniversalDataLogger that this node// is recorded from and that it thus needs to collect data during simulation.if (receptor_type != 0)
{
throw nest::UnknownReceptorType(receptor_type, get_name());
}
return B_.logger_.connect_logging_device(dlr, recordablesMap_);
}
inlinevoidhhca_psc_alpha::get_status(DictionaryDatum &__d)const
{
// parameters
def<double>(__d, "t_ref", get_t_ref());
def<double>(__d, "g_Na", get_g_Na());
def<double>(__d, "g_K", get_g_K());
def<double>(__d, "g_L", get_g_L());
def<double>(__d, "C_m", get_C_m());
def<double>(__d, "E_Na", get_E_Na());
def<double>(__d, "E_K", get_E_K());
def<double>(__d, "E_L", get_E_L());
def<double>(__d, "tau_syn_ex", get_tau_syn_ex());
def<double>(__d, "tau_syn_in", get_tau_syn_in());
def<double>(__d, "g_Ca", get_g_Ca());
def<double>(__d, "Ca_env", get_Ca_env());
def<double>(__d, "Ca_i_eq", get_Ca_i_eq());
def<double>(__d, "tau_Ca", get_tau_Ca());
def<double>(__d, "V_hmCa", get_V_hmCa());
def<double>(__d, "k_mCa", get_k_mCa());
def<double>(__d, "tau_mCa", get_tau_mCa());
def<double>(__d, "V_hhCa", get_V_hhCa());
def<double>(__d, "k_hCa", get_k_hCa());
def<double>(__d, "tau_hCa", get_tau_hCa());
def<double>(__d, "g_AHP", get_g_AHP());
def<double>(__d, "K_AHP", get_K_AHP());
def<double>(__d, "b_AHP", get_b_AHP());
def<double>(__d, "tau_AHP", get_tau_AHP());
def<double>(__d, "E_0", get_E_0());
def<double>(__d, "Vcell", get_Vcell());
def<double>(__d, "I_e", get_I_e());
// initial values for state variables in ODE or kernel
def<long>(__d, "r", get_r());
def<double>(__d, "V_m", get_V_m());
def<double>(__d, "Ca_i", get_Ca_i());
def<double>(__d, "alpha_n_init", get_alpha_n_init());
def<double>(__d, "beta_n_init", get_beta_n_init());
def<double>(__d, "alpha_m_init", get_alpha_m_init());
def<double>(__d, "beta_m_init", get_beta_m_init());
def<double>(__d, "alpha_h_init", get_alpha_h_init());
def<double>(__d, "beta_h_init", get_beta_h_init());
def<double>(__d, "Act_m", get_Act_m());
def<double>(__d, "Inact_h", get_Inact_h());
def<double>(__d, "Act_n", get_Act_n());
def<double>(__d, "h_Ca", get_h_Ca());
def<double>(__d, "m_Ca", get_m_Ca());
def<double>(__d, "m_AHP", get_m_AHP());
def<double>(__d, "I_syn_ex__X__spikeExc", get_I_syn_ex__X__spikeExc());
def<double>(__d, "I_syn_ex__X__spikeExc__d", get_I_syn_ex__X__spikeExc__d());
def<double>(__d, "I_syn_in__X__spikeInh", get_I_syn_in__X__spikeInh());
def<double>(__d, "I_syn_in__X__spikeInh__d", get_I_syn_in__X__spikeInh__d());
ArchivingNode::get_status( __d );
(*__d)[nest::names::recordables] = recordablesMap_.get_list();
def< double >(__d, nest::names::gsl_error_tol, P_.__gsl_error_tol);
if ( P_.__gsl_error_tol <= 0. ){
throw nest::BadProperty( "The gsl_error_tol must be strictly positive." );
}
}
inlinevoidhhca_psc_alpha::set_status(const DictionaryDatum &__d)
{
// parametersdouble tmp_t_ref = get_t_ref();
updateValue<double>(__d, "t_ref", tmp_t_ref);
double tmp_g_Na = get_g_Na();
updateValue<double>(__d, "g_Na", tmp_g_Na);
double tmp_g_K = get_g_K();
updateValue<double>(__d, "g_K", tmp_g_K);
double tmp_g_L = get_g_L();
updateValue<double>(__d, "g_L", tmp_g_L);
double tmp_C_m = get_C_m();
updateValue<double>(__d, "C_m", tmp_C_m);
double tmp_E_Na = get_E_Na();
updateValue<double>(__d, "E_Na", tmp_E_Na);
double tmp_E_K = get_E_K();
updateValue<double>(__d, "E_K", tmp_E_K);
double tmp_E_L = get_E_L();
updateValue<double>(__d, "E_L", tmp_E_L);
double tmp_tau_syn_ex = get_tau_syn_ex();
updateValue<double>(__d, "tau_syn_ex", tmp_tau_syn_ex);
double tmp_tau_syn_in = get_tau_syn_in();
updateValue<double>(__d, "tau_syn_in", tmp_tau_syn_in);
double tmp_g_Ca = get_g_Ca();
updateValue<double>(__d, "g_Ca", tmp_g_Ca);
double tmp_Ca_env = get_Ca_env();
updateValue<double>(__d, "Ca_env", tmp_Ca_env);
double tmp_Ca_i_eq = get_Ca_i_eq();
updateValue<double>(__d, "Ca_i_eq", tmp_Ca_i_eq);
double tmp_tau_Ca = get_tau_Ca();
updateValue<double>(__d, "tau_Ca", tmp_tau_Ca);
double tmp_V_hmCa = get_V_hmCa();
updateValue<double>(__d, "V_hmCa", tmp_V_hmCa);
double tmp_k_mCa = get_k_mCa();
updateValue<double>(__d, "k_mCa", tmp_k_mCa);
double tmp_tau_mCa = get_tau_mCa();
updateValue<double>(__d, "tau_mCa", tmp_tau_mCa);
double tmp_V_hhCa = get_V_hhCa();
updateValue<double>(__d, "V_hhCa", tmp_V_hhCa);
double tmp_k_hCa = get_k_hCa();
updateValue<double>(__d, "k_hCa", tmp_k_hCa);
double tmp_tau_hCa = get_tau_hCa();
updateValue<double>(__d, "tau_hCa", tmp_tau_hCa);
double tmp_g_AHP = get_g_AHP();
updateValue<double>(__d, "g_AHP", tmp_g_AHP);
double tmp_K_AHP = get_K_AHP();
updateValue<double>(__d, "K_AHP", tmp_K_AHP);
double tmp_b_AHP = get_b_AHP();
updateValue<double>(__d, "b_AHP", tmp_b_AHP);
double tmp_tau_AHP = get_tau_AHP();
updateValue<double>(__d, "tau_AHP", tmp_tau_AHP);
double tmp_E_0 = get_E_0();
updateValue<double>(__d, "E_0", tmp_E_0);
double tmp_Vcell = get_Vcell();
updateValue<double>(__d, "Vcell", tmp_Vcell);
double tmp_I_e = get_I_e();
updateValue<double>(__d, "I_e", tmp_I_e);
// initial values for state variables in ODE or kernellong tmp_r = get_r();
updateValue<long>(__d, "r", tmp_r);
double tmp_V_m = get_V_m();
updateValue<double>(__d, "V_m", tmp_V_m);
double tmp_Ca_i = get_Ca_i();
updateValue<double>(__d, "Ca_i", tmp_Ca_i);
double tmp_alpha_n_init = get_alpha_n_init();
updateValue<double>(__d, "alpha_n_init", tmp_alpha_n_init);
double tmp_beta_n_init = get_beta_n_init();
updateValue<double>(__d, "beta_n_init", tmp_beta_n_init);
double tmp_alpha_m_init = get_alpha_m_init();
updateValue<double>(__d, "alpha_m_init", tmp_alpha_m_init);
double tmp_beta_m_init = get_beta_m_init();
updateValue<double>(__d, "beta_m_init", tmp_beta_m_init);
double tmp_alpha_h_init = get_alpha_h_init();
updateValue<double>(__d, "alpha_h_init", tmp_alpha_h_init);
double tmp_beta_h_init = get_beta_h_init();
updateValue<double>(__d, "beta_h_init", tmp_beta_h_init);
double tmp_Act_m = get_Act_m();
updateValue<double>(__d, "Act_m", tmp_Act_m);
double tmp_Inact_h = get_Inact_h();
updateValue<double>(__d, "Inact_h", tmp_Inact_h);
double tmp_Act_n = get_Act_n();
updateValue<double>(__d, "Act_n", tmp_Act_n);
double tmp_h_Ca = get_h_Ca();
updateValue<double>(__d, "h_Ca", tmp_h_Ca);
double tmp_m_Ca = get_m_Ca();
updateValue<double>(__d, "m_Ca", tmp_m_Ca);
double tmp_m_AHP = get_m_AHP();
updateValue<double>(__d, "m_AHP", tmp_m_AHP);
double tmp_I_syn_ex__X__spikeExc = get_I_syn_ex__X__spikeExc();
updateValue<double>(__d, "I_syn_ex__X__spikeExc", tmp_I_syn_ex__X__spikeExc);
double tmp_I_syn_ex__X__spikeExc__d = get_I_syn_ex__X__spikeExc__d();
updateValue<double>(__d, "I_syn_ex__X__spikeExc__d", tmp_I_syn_ex__X__spikeExc__d);
double tmp_I_syn_in__X__spikeInh = get_I_syn_in__X__spikeInh();
updateValue<double>(__d, "I_syn_in__X__spikeInh", tmp_I_syn_in__X__spikeInh);
double tmp_I_syn_in__X__spikeInh__d = get_I_syn_in__X__spikeInh__d();
updateValue<double>(__d, "I_syn_in__X__spikeInh__d", tmp_I_syn_in__X__spikeInh__d);
// We now know that (ptmp, stmp) are consistent. We do not// write them back to (P_, S_) before we are also sure that// the properties to be set in the parent class are internally// consistent.
ArchivingNode::set_status(__d);
// if we get here, temporaries contain consistent set of properties
set_t_ref(tmp_t_ref);
set_g_Na(tmp_g_Na);
set_g_K(tmp_g_K);
set_g_L(tmp_g_L);
set_C_m(tmp_C_m);
set_E_Na(tmp_E_Na);
set_E_K(tmp_E_K);
set_E_L(tmp_E_L);
set_tau_syn_ex(tmp_tau_syn_ex);
set_tau_syn_in(tmp_tau_syn_in);
set_g_Ca(tmp_g_Ca);
set_Ca_env(tmp_Ca_env);
set_Ca_i_eq(tmp_Ca_i_eq);
set_tau_Ca(tmp_tau_Ca);
set_V_hmCa(tmp_V_hmCa);
set_k_mCa(tmp_k_mCa);
set_tau_mCa(tmp_tau_mCa);
set_V_hhCa(tmp_V_hhCa);
set_k_hCa(tmp_k_hCa);
set_tau_hCa(tmp_tau_hCa);
set_g_AHP(tmp_g_AHP);
set_K_AHP(tmp_K_AHP);
set_b_AHP(tmp_b_AHP);
set_tau_AHP(tmp_tau_AHP);
set_E_0(tmp_E_0);
set_Vcell(tmp_Vcell);
set_I_e(tmp_I_e);
set_r(tmp_r);
set_V_m(tmp_V_m);
set_Ca_i(tmp_Ca_i);
set_alpha_n_init(tmp_alpha_n_init);
set_beta_n_init(tmp_beta_n_init);
set_alpha_m_init(tmp_alpha_m_init);
set_beta_m_init(tmp_beta_m_init);
set_alpha_h_init(tmp_alpha_h_init);
set_beta_h_init(tmp_beta_h_init);
set_Act_m(tmp_Act_m);
set_Inact_h(tmp_Inact_h);
set_Act_n(tmp_Act_n);
set_h_Ca(tmp_h_Ca);
set_m_Ca(tmp_m_Ca);
set_m_AHP(tmp_m_AHP);
set_I_syn_ex__X__spikeExc(tmp_I_syn_ex__X__spikeExc);
set_I_syn_ex__X__spikeExc__d(tmp_I_syn_ex__X__spikeExc__d);
set_I_syn_in__X__spikeInh(tmp_I_syn_in__X__spikeInh);
set_I_syn_in__X__spikeInh__d(tmp_I_syn_in__X__spikeInh__d);
updateValue< double >(__d, nest::names::gsl_error_tol, P_.__gsl_error_tol);
if ( P_.__gsl_error_tol <= 0. )
{
throw nest::BadProperty( "The gsl_error_tol must be strictly positive." );
}
};
#endif/* #ifndef HHCA_PSC_ALPHA */