NEURON { POINT_PROCESS pyr2pyr NONSPECIFIC_CURRENT i_nmda, i_ampa RANGE initW RANGE Cdur_nmda, AlphaTmax_nmda, Beta_nmda, Erev_nmda, gbar_nmda, W_nmda, on_nmda, g_nmda RANGE Cdur_ampa, AlphaTmax_ampa, Beta_ampa, Erev_ampa, gbar_ampa, W_ampa, on_ampa, g_ampa RANGE ECa, ICa, P0, fCa, tauCa, iCatotal RANGE Cainf, pooldiam, z RANGE lambda1, lambda2, threshold1, threshold2 RANGE fmax, fmin, Wmax, Wmin, maxChange, normW, scaleW RANGE pregid,postgid :Added by Ali RANGE F, f, tauF, D1, d1, tauD1, D2, d2, tauD2 RANGE facfactor RANGE aACH, bACH, aDA, bDA, wACH, wDA, calcium :Release probability RANGE random, P, P_0 THREADSAFE POINTER randObjPtr } UNITS { (mV) = (millivolt) (nA) = (nanoamp) (uS) = (microsiemens) FARADAY = 96485 (coul) pi = 3.141592 (1) } PARAMETER { : parameters are vars assigned by user or changed by hoc. THey appear in nrnpointmenu initW = 5 Cdur_nmda = 17.58 (ms) AlphaTmax_nmda = .08 (/ms) Beta_nmda = 0.008 (/ms) Erev_nmda = 0 (mV) gbar_nmda = .6e-3 (uS) Cdur_ampa = 5.31 (ms) AlphaTmax_ampa = 0.117 (/ms) Beta_ampa = 0.090 (/ms) Erev_ampa = 0 (mV) gbar_ampa = 1.7e-3 (uS) ECa = 120 Cainf = 50e-6 (mM) pooldiam = 1.8172 (micrometer) z = 2 tauCa = 50 (ms) P0 = .015 fCa = .024 lambda1 = 2.5 lambda2 = .01 threshold1 = 0.2 (uM) threshold2 = 0.4 (uM) fmax = 3 fmin = .8 :Added by Ali ACH = 1 DA = 1 LearningShutDown = 0 facfactor = 1 : the (1) is needed for the range limits to be effective f = 1 (1) < 0, 1e9 > : facilitation tauF = 1 (ms) < 1e-9, 1e9 > d1 = 1 (1) < 0, 1 > : fast depression tauD1 = 1 (ms) < 1e-9, 1e9 > d2 = 1 (1) < 0, 1 > : slow depression tauD2 = 1 (ms) < 1e-9, 1e9 > aACH = 1 bACH = 0 wACH = 0 aDA = 1 bDA = 0 wDA = 0 P_0 = 1 (1) < 0, 1 > : base release probability } ASSIGNED { : These are vars calculated by Neuron hoc or by the mechanism mod itself v (mV) i_nmda (nA) g_nmda (uS) on_nmda W_nmda i_ampa (nA) g_ampa (uS) on_ampa W_ampa t0 (ms) ICa (mA) Afactor (mM/ms/nA) iCatotal (mA) dW_ampa Wmax Wmin maxChange normW scaleW pregid postgid :Added by Ali calcium tsyn fa F D1 D2 :Release probability P : instantaneous release probability randObjPtr : pointer to a hoc random number generator Random.uniform(0,1) random : individual instance of random number } STATE { r_nmda r_ampa Capoolcon } INITIAL { on_nmda = 0 r_nmda = 0 W_nmda = initW on_ampa = 0 r_ampa = 0 W_ampa = initW t0 = -1 :Wmax = 2*initW :Wmin = 0.25*initW maxChange = (Wmax-Wmin)/10 dW_ampa = 0 Capoolcon = Cainf Afactor = 1/(z*FARADAY*4/3*pi*(pooldiam/2)^3)*(1e6) :Added by Ali tsyn = -1e30 fa =0 F = 1 D1 = 1 D2 = 1 P = P_0 random = 1 } BREAKPOINT { SOLVE release METHOD cnexp } DERIVATIVE release { if (t0>0) { if (t-t0 < Cdur_nmda) { on_nmda = 1 } else { on_nmda = 0 } if (t-t0 < Cdur_ampa) { on_ampa = 1 } else { on_ampa = 0 } } r_nmda' = AlphaTmax_nmda*on_nmda*(1-r_nmda) -Beta_nmda*r_nmda r_ampa' = AlphaTmax_ampa*on_ampa*(1-r_ampa) -Beta_ampa*r_ampa dW_ampa = eta(Capoolcon)*(lambda1*omega(Capoolcon, threshold1, threshold2)-lambda2*W_ampa)*dt : Limit for extreme large weight changes if (fabs(dW_ampa) > maxChange) { if (dW_ampa < 0) { dW_ampa = -1*maxChange } else { dW_ampa = maxChange } } :Normalize the weight change normW = (W_ampa-Wmin)/(Wmax-Wmin) if (dW_ampa < 0) { scaleW = sqrt(fabs(normW)) } else { scaleW = sqrt(fabs(1.0-normW)) } W_ampa = W_ampa + dW_ampa*scaleW *(1+ (wACH * (ACH - 1))) * LearningShutDown :Weight value limits if (W_ampa > Wmax) { W_ampa = Wmax } else if (W_ampa < Wmin) { W_ampa = Wmin } g_nmda = gbar_nmda*r_nmda * facfactor i_nmda = W_nmda*g_nmda*(v - Erev_nmda)*sfunc(v) g_ampa = gbar_ampa*r_ampa * facfactor i_ampa = W_ampa*g_ampa*(v - Erev_ampa) * (1 + (bACH * (ACH-1)))*(aDA + (bDA * (DA-1))) ICa = P0*g_nmda*(v - ECa)*sfunc(v) Capoolcon'= -fCa*Afactor*ICa + (Cainf-Capoolcon)/tauCa } NET_RECEIVE(dummy_weight) { random = randGen() if (random < P_0) { t0 = t :spike time for conductance opening :Added by Ali, Synaptic facilitation F = 1 + (F-1)* exp(-(t - tsyn)/tauF) D1 = 1 - (1-D1)*exp(-(t - tsyn)/tauD1) D2 = 1 - (1-D2)*exp(-(t - tsyn)/tauD2) :printf("%g\t%g\t%g\t%g\t%g\t%g\n", t, t-tsyn, F, D1, D2, facfactor) :if (P_0*F*D1 > 1) { : P = 1 :} else { : P = P_0*F*D1*D2 :} :random = randGen() :if (random <= P) { :net_event(t) :} tsyn = t facfactor = F * D1 * D2 F = F * f if (F > 30) { F=30 } D1 = D1 * d1 D2 = D2 * d2 } :printf("\t%g\t%g\t%g\n", F, D1, D2) } :::::::::::: FUNCTIONs and PROCEDUREs :::::::::::: FUNCTION sfunc (v (mV)) { UNITSOFF sfunc = 1/(1+0.33*exp(-0.06*v)) UNITSON } FUNCTION eta(Cani (mM)) { LOCAL taulearn, P1, P2, P4, Cacon P1 = 0.1 P2 = P1*1e-4 P4 = 1 Cacon = Cani*1e3 taulearn = P1/(P2+Cacon*Cacon*Cacon)+P4 eta = 1/taulearn*0.001 } FUNCTION omega(Cani (mM), threshold1 (uM), threshold2 (uM)) { LOCAL r, mid, Cacon Cacon = Cani*1e3 r = (threshold2-threshold1)/2 mid = (threshold1+threshold2)/2 if (Cacon <= threshold1) { omega = 0} else if (Cacon >= threshold2) { omega = 1/(1+50*exp(-50*(Cacon-threshold2)))} else {omega = -sqrt(r*r-(Cacon-mid)*(Cacon-mid))} } VERBATIM double nrn_random_pick(void* r); void* nrn_random_arg(int argpos); ENDVERBATIM FUNCTION randGen() { VERBATIM if (_p_randObjPtr) { /* :Supports separate independent but reproducible streams for : each instance. However, the corresponding hoc Random : distribution MUST be set to Random.uniform(0,1) */ _lrandGen = nrn_random_pick(_p_randObjPtr); }else{ hoc_execerror("Random object ref not set correctly for randObjPtr"," only via hoc Random"); } ENDVERBATIM } PROCEDURE setRandObjRef() { VERBATIM void** pv4 = (void**)(&_p_randObjPtr); if (ifarg(1)) { *pv4 = nrn_random_arg(1); }else{ *pv4 = (void*)0; } ENDVERBATIM }