;; Cerebellar Purkinje Cell: resurgent Na current and high frequency ;; firing (Khaliq et al 2003). (nemo-model Khaliq03 ( (input v) (const ena = 60) (const ek = -88) (const ca0 = 1e-4) (component (type decaying-pool) (name ca) (input (ica from ion-currents)) (const F = 96485.309) (const ca_depth = 0.1) (const ca_beta = 1.0) (const cao = 2.4) (d (ca) = ((neg (ica) / (2 * ca0 * F * ca_depth)) - ((if (ca < ca0) then ca0 else ca) * ca_beta)) (initial ca0)) (cac = (if (ca < ca0) then ca0 else ca)) (output cac cao)) (component (type membrane-capacitance) (const C_m = (1)) (output C_m)) (component (type geometry) (name soma) (const L = 20) (const diam = 20) (output L diam )) (component (type ionic-current) (name CaBK) ;: BK-type Purkinje calcium-activated potassium current (input (cai from ion-pools) (cao from ion-pools)) (component (type gate) ;; constants (const ztau = 1.0) ;; rate functions (CaBK_v = (v + 5)) (minf = (let ((vh -28.9) (k 6.2)) (1.0 / (1.0 + exp (neg ((CaBK_v - vh) / k)))))) (mtau = (let ((y0 0.000505) (vh1 -33.3) (k1 -10.0) (vh2 86.4) (k2 10.1)) ((1e3) * (y0 + 1 / (exp ((CaBK_v + vh1) / k1) + exp ((CaBK_v + vh2) / k2)))))) (hinf = (let ((y0 0.085) (vh -32.0) (k 5.8)) (y0 + (1 - y0) / (1 + exp ((CaBK_v - vh) / k))))) (htau = (let ((y0 0.0019) (vh1 -54.2) (k1 -12.9) (vh2 48.5) (k2 5.2)) ((1e3) * (y0 + 1 / (exp ((CaBK_v + vh1) / k1) + exp ((CaBK_v + vh2) / k2)))))) (zinf = (let ((k 0.001)) (1 / (1 + (k / cai))))) (z_alpha = (zinf / ztau)) (z_beta = ((1 - zinf) / ztau)) (reaction (z (transitions (<-> O C z_alpha z_beta)) (conserve ((1 = (O + C)))) (initial (let ((k 0.001)) (1 / (1 + k / ca0)))) (open O) (power 2))) (output z) (hh-ionic-gate (CaBK ;; ion name: exported variables will be of the form {ion}_{id} (initial-m (minf)) (initial-h (hinf)) (m-power 3) (h-power 1) (m-inf (minf)) (m-tau (mtau)) (h-inf (hinf)) (h-tau (htau)))) ) (component (type pore) (const gbar_CaBK = 0.007) (output gbar_CaBK )) (component (type permeating-ion) (name k) (const e_CaBK = ek) (output e_CaBK)) ;; end BK current ) (component (type ionic-current) (name CaP) ;; HH P-type Calcium current (input (cai from ion-pools) (cao from ion-pools)) (component (type gate) ;; rate functions (inf = (let ((cv -19) (ck 5.5)) (1.0 / (1.0 + exp (neg ((v - cv) / ck)))))) (tau = ((1e3) * (if (v > -50) then (0.000191 + (0.00376 * exp (neg (((v + 41.9) / 27.8) ^ 2)))) else (0.00026367 + (0.1278 * exp (0.10327 * v)))))) (hh-ionic-gate (CaP ;; ion name: exported variables will be of the form {ion}_{id} (initial-m (inf)) (m-power 1) (h-power 0) (m-inf inf) (m-tau tau))) ) (component (type permeability) (fun ghk (v ci co) (let ((F 9.6485e4) (R 8.3145) (T (22 + 273.19)) (Z 2) (E ((1e-3) * v))) (let ((k0 ((Z * (F * E)) / (R * T)))) (let ((k1 (exp (neg (k0)))) (k2 (((Z ^ 2) * (E * (F ^ 2))) / (R * T)))) (1e-6) * (if (abs (1 - k1) < 1e-6) then (Z * F * (ci - (co * k1)) * (1 - k0)) else (k2 * (ci - (co * k1)) / (1 - k1))))))) (const pcabar = 0.00005) (pca = (pcabar * ghk (v cai cao))) (output pca pcabar)) (component (type permeating-ion) (name ca)) ;; end CaP current ) (component (type ionic-current) (name K1) ;; HH TEA-sensitive Purkinje potassium current (component (type gate) ;; constants ;; rate functions (K1_v = (v + 11)) ;; account for junction potential (minf = (let ((mivh -24) (mik 15.4)) (1 / (1 + exp (neg (K1_v - mivh) / mik))))) (mtau = (let ((mty0 0.00012851) (mtvh1 100.7) (mtk1 12.9) (mtvh2 -56.0) (mtk2 -23.1)) (1e3 * (if (K1_v < -35) then (3.0 * (3.4225e-5 + 0.00498 * exp (neg (K1_v) / -28.29))) else (mty0 + 1.0 / (exp ((K1_v + mtvh1) / mtk1) + exp ((K1_v + mtvh2) / mtk2))) )))) (hinf = (let ((hiy0 0.31) (hiA 0.78) (hivh -5.802) (hik 11.2)) (hiy0 + hiA / (1 + exp ((K1_v - hivh) / hik))))) (htau = (1e3 * (if ( K1_v > 0 ) then (0.0012 + 0.0023 * exp (-0.141 * K1_v)) else (1.2202e-05 + 0.012 * exp (neg (((K1_v - (-56.3)) / 49.6) ^ 2)))))) (hh-ionic-gate (K1 ;; ion name: exported variables will be of the form {ion}_{id} (initial-m (minf)) (initial-h (hinf)) (m-power 3) (h-power 1) (m-inf (minf)) (m-tau (mtau)) (h-inf (hinf)) (h-tau (htau)))) ) (component (type pore) (const gbar = 0.004) (output gbar)) (component (type permeating-ion) (name k) (const e = ek) (output e)) ;; end K1 current ) (component (type ionic-current) (name K2) ;; HH Low TEA-sensitive Purkinje potassium current (component (type gate) ;; constants ;; rate functions (K2_v = (v + 11)) ;; account for junction potential (minf = (let ((mivh -24) (mik 20.4)) (1 / (1 + exp ((neg (K2_v - mivh)) / mik))))) (mtau = ((1e3) * (if (K2_v < -20) then (0.000688 + 1 / (exp ((K2_v + 64.2) / 6.5) + exp ((K2_v - 141.5) / -34.8))) else (0.00016 + 0.0008 * exp (-0.0267 * K2_v))))) (hh-ionic-gate (K2 ;; ion name: exported variables will be of the form {ion}_{id} (initial-m (minf)) (m-power 4) (h-power 0) (m-inf (minf)) (m-tau (mtau)))) ) (component (type pore) (const gbar = 0.002) (output gbar)) (component (type permeating-ion) (name k) (const e = ek) (output e)) ;; end K2 current ) (component (type ionic-current) (name K3) ;; HH slow TEA-insensitive Purkinje potassium current (component (type gate) ;; constants ;; rate functions (K3_v = (v + 11)) ;; account for junction potential (minf = (let ((mivh -16.5) (mik 18.4)) (1 / (1 + exp ((neg (K3_v - mivh)) / mik))))) (mtau = ((1e3) * (0.000796 + 1.0 / (exp ((K3_v + 73.2) / 11.7) + exp ((K3_v - 306.7) / -74.2))))) (hh-ionic-gate (K3 ;; ion name: exported variables will be of the form {ion}_{id} (initial-m (minf)) (m-power 4) (h-power 0) (m-inf (minf)) (m-tau (mtau)))) ) (component (type pore) (const gbar = 0.004) (output gbar)) (component (type permeating-ion) (name k) (const e = ek) (output e)) ;; end K3 current ) (component (type ionic-current) (name Narsg) ;; constants (component (type gate) (const Con = 0.005) (const Coff = 0.5) (const Oon = 0.75) (const Ooff = 0.005) (const alfac = (pow ((Oon / Con) (1.0 / 4.0)))) (const btfac = (pow ((Ooff / Coff) (1.0 / 4.0)))) (const alpha = 150) (const beta = 3) (const gamma = 150) (const delta = 40) (const epsilon = 1.75) (const zeta = 0.03) (const x1 = 20) (const x2 = -20) (const x3 = 1e12) (const x4 = -1e12) (const x5 = 1e12) (const x6 = -25) ;; rate functions (f01 = (4.0 * alpha * exp (v / x1))) (f02 = (3.0 * alpha * exp (v / x1))) (f03 = (2.0 * alpha * exp (v / x1))) (f04 = (alpha * exp (v / x1))) (f0O = (gamma * exp (v / x3))) (fip = (epsilon * exp (v / x5))) (f11 = (4.0 * alpha * alfac * exp (v / x1))) (f12 = (3.0 * alpha * alfac * exp (v / x1))) (f13 = (2.0 * alpha * alfac * exp (v / x1))) (f14 = (alpha * alfac * exp (v / x1))) (f1n = (gamma * exp (v / x3))) (fi1 = (Con)) (fi2 = (Con * alfac)) (fi3 = (Con * alfac * alfac)) (fi4 = (Con * alfac * alfac * alfac)) (fi5 = (Con * alfac * alfac * alfac * alfac)) (fin = (Oon)) (b01 = (beta * exp (v / x2))) (b02 = (2.0 * beta * exp (v / x2))) (b03 = (3.0 * beta * exp (v / x2))) (b04 = (4.0 * beta * exp (v / x2))) (b0O = (delta * exp (v / x4))) (bip = (zeta * exp (v / x6))) (b11 = (beta * btfac * exp (v / x2))) (b12 = (2.0 * beta * btfac * exp (v / x2))) (b13 = (3.0 * beta * btfac * exp (v / x2))) (b14 = (4.0 * beta * btfac * exp (v / x2))) (b1n = (delta * exp (v / x4))) (bi1 = (Coff)) (bi2 = (Coff * btfac)) (bi3 = (Coff * btfac * btfac)) (bi4 = (Coff * btfac * btfac * btfac)) (bi5 = (Coff * btfac * btfac * btfac * btfac)) (bin = (Ooff)) (reaction (Narsg_z (transitions (<-> C1 C2 f01 b01) (<-> C2 C3 f02 b02) (<-> C3 C4 f03 b03) (<-> C4 C5 f04 b04) (<-> C5 O f0O b0O) (<-> O B fip bip) (<-> O I6 fin bin) (<-> C1 I1 fi1 bi1) (<-> C2 I2 fi2 bi2) (<-> C3 I3 fi3 bi3) (<-> C4 I4 fi4 bi4) (<-> C5 I5 fi5 bi5) (<-> I1 I2 f11 b11) (<-> I2 I3 f12 b12) (<-> I3 I4 f13 b13) (<-> I4 I5 f14 b14) (<-> I5 I6 f1n b1n) ) (conserve ((1 = (I1 + I2 + I3 + I4 + I5 + I6 + C1 + C2 + C3 + C4 + C5 + O + B)))) (open O) (power 1)) ) (output Narsg_z) ) (component (type pore) (const gbar = 0.015) (output gbar)) (component (type permeating-ion) (name na) (const e = ena) (output e)) ) (component (type ionic-current) (name Ih) (component (type gate) ;; rate functions (inf = (1.0 / (1.0 + exp ((v + 90.1) / 9.9)))) (tau = ((1e3) * (0.19 + 0.72 * exp (neg (((v - (-81.5)) / 11.9) ^ 2))))) (hh-ionic-gate (Ih ;; ion name: exported variables will be of the form {ion}_{id} (initial-m (inf)) (m-power 1) (h-power 0) (m-inf (inf)) (m-tau (tau)))) ) (component (type pore) (const gbar = 0.0001) (output gbar)) (component (type permeating-ion) (name non-specific) (const e = -30) (output e)) ;; end Ih current ) (component (type ionic-current) (name Leak) (component (type pore) (const gbar = 5e-5) (output gbar)) (component (type permeating-ion) (name non-specific) (const e = -60) (output e)) ;; end leak current ) (component (type voltage-clamp) (name K1) (const vchold = -71) (const vcbase = -69) (const vcinc = 10) (const vcsteps = 8) (const vchdur = 30) (const vcbdur = 100) (output vchold vcbase vcinc vcsteps vchdur vcbdur) ) (component (type voltage-clamp) (name K2) (const vchold = -71) (const vcbase = -69) (const vcinc = 10) (const vcsteps = 9) (const vchdur = 30) (const vcbdur = 100) (output vchold vcbase vcinc vcsteps vchdur vcbdur) ) (component (type voltage-clamp) (name K3) (const vchold = -71) (const vcbase = -61) (const vcinc = 10) (const vcsteps = 8) (const vchdur = 30) (const vcbdur = 100) (output vchold vcbase vcinc vcsteps vchdur vcbdur) ) (component (type voltage-clamp) (name CaBK) (const vchold = -90) (const vcbase = -40) (const vcinc = 10) (const vcsteps = 5) (const vchdur = 5) (const vcbdur = 20) (component (type default-concentration) (name ca) (const cn = 1e-4) (const cnout = 2) (output cn cnout)) (output vchold vcbase vcinc vcsteps vchdur vcbdur) ) (component (type voltage-clamp) (name CaP) (const vchold = -90) (const vcbase = -90) (const vcinc = 10) (const vcsteps = 11) (const vchdur = 5) (const vcbdur = 10) (component (type default-concentration) (name ca) (const cn = 1e-4) (const cnout = 2) (output cn cnout)) (output vchold vcbase vcinc vcsteps vchdur vcbdur) ) (component (type voltage-clamp) (name Ih) (const vchold = -50) (const vcbase = -60) (const vcinc = -10) (const vcsteps = 7) (const vchdur = 100) (const vcbdur = 200) (output vchold vcbase vcinc vcsteps vchdur vcbdur) ) (component (type voltage-clamp) (name Narsg) (const vchold = -71) (const vcbase = -60) (const vcinc = 10) (const vcsteps = 9) (const vchdur = 30) (const vcbdur = 100) (output vchold vcbase vcinc vcsteps vchdur vcbdur) ) ) ;; Following are templates for various driver scripts used to run this model ( (".hoc" () #< Removing old automake cache ..." rm -rf autom4te.cache fi echo " -> Running aclocal ..." aclocal echo " -> Running libtoolize ..." if [ `uname -s` = Darwin ] ; then # libtoolize is glibtoolize on OSX LIBTOOLIZE=glibtoolize else LIBTOOLIZE=libtoolize fi libtool_major=`$LIBTOOLIZE --version | head -n1 | cut -d\) -f2 | cut -d\. -f1` $LIBTOOLIZE --force --copy --ltdl echo " -> Re-running aclocal ..." if test $libtool_major -le 2; then aclocal --force else aclocal --force -I $(pwd)/libltdl/m4 fi echo " -> Running autoconf ..." autoconf # autoheader must run before automake echo " -> Running autoheader ..." autoheader echo " -> Running automake ..." automake --foreign --add-missing --force-missing --copy echo "Done." EOF ) ("nestmodule_configure.ac" () #<_LTX_mod * * The dynamicloader can then load modulename and search for symbol "mod" in it. */ {{model_name}}nest::{{model_name}}Module {{model_name}}module_LTX_mod; // -- DynModule functions ------------------------------------------------------ {{model_name}}nest::{{model_name}}Module::{{model_name}}Module() { #ifdef LINKED_MODULE // register this module at the dynamic loader // this is needed to allow for linking in this module at compile time // all registered modules will be initialized by the main app's dynamic loader nest::DynamicLoaderModule::registerLinkedModule(this); #endif } {{model_name}}nest::{{model_name}}Module::~{{model_name}}Module() { } const std::string {{model_name}}nest::{{model_name}}Module::name(void) const { return std::string("{{model_name}} Module"); // Return name of the module } const std::string {{model_name}}nest::{{model_name}}Module::commandstring(void) const { /* 1. Tell interpreter that we provide the C++ part of {{model_name}}Module with the current revision number. 2. Instruct the interpreter to check that {{model_name}}module-init.sli exists, provides at least version 1.0 of the SLI interface to {{model_name}}Module, and to load it. */ return std::string( "/{{model_name}}module /C++ ($Revision: 8512 $) provide-component " "/{{model_name}}module /SLI (7165) require-component" ); } /* BeginDocumentation Name: StepPatternConnect - Connect sources and targets with a stepping pattern Synopsis: [sources] source_step [targets] target_step synmod StepPatternConnect -> n_connections Parameters: [sources] - Array containing GIDs of potential source neurons source_step - Make connection from every source_step'th neuron [targets] - Array containing GIDs of potential target neurons target_step - Make connection to every target_step'th neuron synmod - The synapse model to use (literal, must be key in synapsedict) n_connections - Number of connections made Description: This function subsamples the source and target arrays given with steps source_step and target_step, beginning with the first element in each array, and connects the selected nodes. Example: /first_src 0 /network_size get def /last_src /iaf_neuron 20 Create def % nodes 1 .. 20 /src [first_src last_src] Range def /last_tgt /iaf_neuron 10 Create def % nodes 21 .. 30 /tgt [last_src 1 add last_tgt] Range def src 6 tgt 4 /drop_odd_spike StepPatternConnect This connects nodes [1, 7, 13, 19] as sources to nodes [21, 25, 29] as targets using synapses of type drop_odd_spike, and returning 12 as the number of connections. The following command will print the connections (you must paste the SLI command as one long line): src { /s Set << /source s /synapse_type /static_synapse >> FindConnections { GetStatus /target get } Map dup length 0 gt { cout s <- ( -> ) <- exch <-- endl } if ; } forall 1 -> [21 25 29] 7 -> [21 25 29] 13 -> [21 25 29] 19 -> [21 25 29] Remark: This function is only provided as an example for how to write your own interface function. Author: Hans Ekkehard Plesser SeeAlso: Connect, ConvergentConnect, DivergentConnect */ void {{model_name}}nest::{{model_name}}Module::StepPatternConnect_Vi_i_Vi_i_lFunction::execute(SLIInterpreter *i) const { // Check if we have (at least) five arguments on the stack. i->assert_stack_load(5); // Retrieve source, source step, target, target step from the stack const TokenArray sources = getValue (i->OStack.pick(4)); // bottom const long src_step = getValue (i->OStack.pick(3)); const TokenArray targets = getValue (i->OStack.pick(2)); const long tgt_step = getValue (i->OStack.pick(1)); const Name synmodel_name = getValue(i->OStack.pick(0)); // top // Obtain synapse model index const Token synmodel = nest::NestModule::get_network().get_synapsedict().lookup(synmodel_name); if ( synmodel.empty() ) throw nest::UnknownSynapseType(synmodel_name.toString()); const nest::index synmodel_id = static_cast(synmodel); // Build a list of targets with the given step TokenArray selected_targets; for ( size_t t = 0 ; t < targets.size() ; t += tgt_step ) selected_targets.push_back(targets[t]); // Now connect all appropriate sources to this list of targets size_t Nconn = 0; // counts connections for ( size_t s = 0 ; s < sources.size() ; s += src_step ) { // We must first obtain the GID of the source as integer const nest::long_t sgid = getValue(sources[s]); // nest::network::divergent_connect() requires weight and delay arrays. We want to use // default values from the synapse model, so we pass empty arrays. nest::NestModule::get_network().divergent_connect(sgid, selected_targets, TokenArray(), TokenArray(), synmodel_id); Nconn += selected_targets.size(); } // We get here only if none of the operations above throws and exception. // Now we can safely remove the arguments from the stack and push Nconn // as our result. i->OStack.pop(5); i->OStack.push(Nconn); // Finally, we pop the call to this functions from the execution stack. i->EStack.pop(); } //------------------------------------------------------------------------------------- void {{model_name}}nest::{{model_name}}Module::init(SLIInterpreter *i, nest::Network*) { /* Register a neuron or device model. Give node type as template argument and the name as second argument. The first argument is always a reference to the network. Return value is a handle for later unregistration. */ //printf ("before register model\n"); nest::register_model(nest::NestModule::get_network(), "{{model_name}}"); // printf ("after register model\n"); /* Register a synapse type. Give synapse type as template argument and the name as second argument. The first argument is always a reference to the network. */ nest::register_prototype_connection(nest::NestModule::get_network(), "drop_odd_synapse"); /* Register a SLI function. The first argument is the function name for SLI, the second a pointer to the function object. If you do not want to overload the function in SLI, you do not need to give the mangled name. If you give a mangled name, you should define a type trie in the {{model_name}}module-init.sli file. */ i->createcommand("StepPatternConnect_Vi_i_Vi_i_l", &stepPatternConnect_Vi_i_Vi_i_lFunction); } // {{model_name}}Module::init() EOF ) ("nestmodule.h" () #<> SetStatus /neuron /{{model_name}} Create def /neuron_params << /V_m -65.0 >> def neuron neuron_params SetStatus /stepinput /step_current_generator Create def /vlog /voltmeter Create def /vlog_parameters << /interval dt /to_file true /to_memory false >> def vlog vlog_parameters SetStatus stepinput neuron Connect vlog neuron Connect /step_current_parameters << /amplitude_times [0.0 1000.0 2850.0] /amplitude_values [0. 18.75 0. ] >> def stepinput step_current_parameters SetStatus 3000.0 Simulate EOF ) ))