def K_BK_Chan(name): K_BK = moose.HHChannel2D('/library/' + name) K_BK.Ek = EK K_BK.Gbar = 300.0 * SOMA_A K_BK.Gk = 0.0 K_BK.Xpower = 0.0 K_BK.Ypower = 0.0 K_BK.Zpower = 1.0 K_BK.Zindex = 'VOLT_C1_INDEX' # cai = 5.e-5 # d1 = .84 # d2 = 1. # k1 = .48e-3 # k2 = .13e-6 # abar = .28 # bbar = .48 # st=1 # tfactor = 1 # F_KC = F/1000.0 # # def exp1(k,d,v): # return k*np.exp(-2*d*F_KC*v*1e3/R/(273.15 + celsius)) # def alp(v,c): # return c*abar/(c + exp1(k1,d1,v)) # def bet(v,c): # return bbar/(1 + c/exp1(k2,d2,v)) zgate = moose.element(K_BK.path + '/gateZ') zgate.xminA = Vmin zgate.xmaxA = Vmax zgate.xdivsA = Vdivs zgate.yminA = Camin zgate.ymaxA = Camax zgate.ydivsA = Cadivs zgate.xminB = Vmin zgate.xmaxB = Vmax zgate.xdivsB = Vdivs zgate.yminB = Camin zgate.ymaxB = Camax zgate.ydivsB = Cadivs # x = Vmin # tblA = np.zeros([len(v),len(ca)]) # tblB = np.zeros([len(v),len(ca)]) # for i in np.arange(len(v)): # tblA[i] = np.array([alp(x,y) for y in ca]) # tblB[i] = np.add(tblA[i],[bet(x, y) for y in ca])/tfactor # x = x + dV # print(i, end='\r') # # zgate.tableA = tblA*1e3 # zgate.tableB = tblB*1e3 zgate.tableA = tblA zgate.tableB = tblB addmsg4 = moose.Mstring(K_BK.path + '/addmsg4') addmsg4.value = '../Ca_conc concOut . concen' return K_BK
def K_BK_Chan(name): K_BK = moose.HHChannel2D( '/library/' + name ) K_BK.Ek = EK K_BK.Gbar = 300.0*SOMA_A K_BK.Gk = 0.0 K_BK.Xpower = 0.0 K_BK.Ypower = 0.0 K_BK.Zpower = 1.0 K_BK.Zindex = 'VOLT_C1_INDEX' zgate = moose.element( K_BK.path + '/gateZ' ) zgate.xminA = Vmin zgate.xmaxA = Vmax zgate.xdivsA = Vdivs zgate.yminA = Camin zgate.ymaxA = Camax zgate.ydivsA = Cadivs zgate.xminB = Vmin zgate.xmaxB = Vmax zgate.xdivsB = Vdivs zgate.yminB = Camin zgate.ymaxB = Camax zgate.ydivsB = Cadivs zgate.tableA = tblA*1e3 zgate.tableB = tblB*1e3 addmsg4 = moose.Mstring( K_BK.path + '/addmsg4' ) addmsg4.value = '../Ca_conc concOut . concen' return K_BK
def KBK_Chan(name): KBK = moose.HHChannel2D('/library/' + name) KBK.Ek = EK KBK.Gbar = 300.0 * SOMA_A KBK.Gk = 0.0 KBK.Xpower = 0.0 KBK.Ypower = 0.0 KBK.Zpower = 1.0 KBK.Zindex = 'VOLT_C1_INDEX' cai = 5.e-5 d1 = .84 d2 = 1. k1 = 0.000588 k2 = 8.76481e-08 abar = .28 bbar = .48 st = 1 tfactor = 1.279493 F_KC = F / 1000.0 def exp1(k, d, v): return k * np.exp(-2 * d * F_KC * v * 1e3 / R / (273.15 + celsius)) def alp(v, c): return c * abar / (c + exp1(k1, d1, v)) def bet(v, c): return bbar / (1 + c / exp1(k2, d2, v)) zgate = moose.element(KBK.path + '/gateZ') zgate.xminA = Vmin zgate.xmaxA = Vmax zgate.xdivsA = Vdivs zgate.yminA = Camin zgate.ymaxA = Camax zgate.ydivsA = Cadivs zgate.xminB = Vmin zgate.xmaxB = Vmax zgate.xdivsB = Vdivs zgate.yminB = Camin zgate.ymaxB = Camax zgate.ydivsB = Cadivs x = Vmin tblA = np.zeros([len(v), len(ca)]) tblB = np.zeros([len(v), len(ca)]) for i in np.arange(len(v)): tblA[i] = np.array([alp(x, y) for y in ca]) tblB[i] = np.add(tblA[i], [bet(x, y) for y in ca]) / tfactor x = x + dV print(i, end='\r') zgate.tableA = tblA * 1e3 zgate.tableB = tblB * 1e3 addmsg4 = moose.Mstring(KBK.path + '/addmsg4') addmsg4.value = '../Ca_conc concOut . concen' return KBK
def KmAHP_Chan(name): KmAHP = moose.HHChannel2D('/library/' + name) KmAHP.Ek = EK KmAHP.Gbar = 300.0 * SOMA_A KmAHP.Gk = 0.0 KmAHP.Xpower = 0.0 KmAHP.Ypower = 0.0 KmAHP.Zpower = 1.0 KmAHP.Zindex = 'VOLT_C1_INDEX' celsius = 20 gkbar = 0.01e4 d1 = 1 d2 = 1.5 k1 = 0.18 k2 = 0.011 bbar = 0.28e3 abar = 0.48e3 F_KC = F / 1000.0 def alp(v, c): return c * abar / (c + k1 * np.exp(-2 * d1 * F * v / R / (273.15 + celsius))) def bet(v, c): return bbar / (1 + c / (k2 * np.exp(-2 * d2 * F * v / R / (273.15 + celsius)))) zgate = moose.element(KmAHP.path + '/gateZ') zgate.xminA = Vmin zgate.xmaxA = Vmax zgate.xdivsA = Vdivs zgate.yminA = Camin zgate.ymaxA = Camax zgate.ydivsA = Cadivs zgate.xminB = Vmin zgate.xmaxB = Vmax zgate.xdivsB = Vdivs zgate.yminB = Camin zgate.ymaxB = Camax zgate.ydivsB = Cadivs x = Vmin tblA = np.zeros([Vdivs + 1, Cadivs + 2]) tblB = np.zeros([Vdivs + 1, Cadivs + 2]) for i in np.arange(Vdivs + 1): tblA[i] = [alp(x, y) for y in np.arange(Camin, Camax + dCa, dCa)] tblB[i] = np.add( tblA[i], [bet(x, y) for y in np.arange(Camin, Camax + dCa, dCa)]) x = x + dV print(i, end='\r') zgate.tableA = tblA * 1e3 zgate.tableB = tblB * 1e3 addmsg4 = moose.Mstring(KmAHP.path + '/addmsg4') addmsg4.value = '../Ca_conc concOut . concen' return KmAHP
def K_BK_Chan(name): K_BK = moose.HHChannel2D('/library/' + name) K_BK.Ek = EK K_BK.Gbar = 300.0 * SOMA_A K_BK.Gk = 0.0 K_BK.Xpower = 1.0 K_BK.Ypower = 0.0 K_BK.Zpower = 0.0 K_BK.Xindex = 'VOLT_C1_INDEX' xgate = moose.element(K_BK.path + '/gateX') xgate.xminA = Vmin xgate.xmaxA = Vmax xgate.xdivsA = Vdivs xgate.yminA = Camin xgate.ymaxA = Camax xgate.ydivsA = Cadivs xgate.xminB = Vmin xgate.xmaxB = Vmax xgate.xdivsB = Vdivs xgate.yminB = Camin xgate.ymaxB = Camax xgate.ydivsB = Cadivs d1 = .84 d2 = 1. k1 = .48e-3 k2 = .13e-6 abar = .28 bbar = .48 st = 1 F_KC = F / 1000 gbar = .01e4 exp1k1d1 = k1 * np.exp(-2 * d1 * F_KC * v * 1e3 / R / (273.15 + celsius)) exp1k2d2 = k2 * np.exp(-2 * d2 * F_KC * v * 1e3 / R / (273.15 + celsius)) tblA = np.zeros([Vdivs, Cadivs]) tblB = np.zeros([Vdivs, Cadivs]) for i in np.arange(Cadivs): tblA[:, i] = ca[i] * abar / (ca[i] + exp1k1d1) tblB[:, i] = tblA[:, i] + bbar / (1 + ca[i] / exp1k2d2) print(i, end='\r') xgate.tableA = tblA * 1e3 xgate.tableB = tblB * 1e3 # print(np.array(xgate.tableA)/np.array(xgate.tableB)) addmsg4 = moose.Mstring(K_BK.path + '/addmsg4') addmsg4.value = '../Ca_conc concOut . concen' return K_BK
def BKchan_proto(chanparams, VDIVS=3000, VMIN=-100e-3, VMAX=50e-3, CAMIN=0, CAMAX=1, CADIVS=5000): ZFbyRT = 2 * 96520 / (8.3134 * (23 + 273.15)) v_array = np.linspace(VMIN, VMAX, VDIVS) ca_array = np.linspace(CAMIN, CAMAX, CADIVS) #set up the two dimensional gating matrix: gatingMatrix = [] for i, pars in enumerate(chanparams.Xparam): Vdepgating = pars.K * np.exp(pars.delta * ZFbyRT * v_array) #These assignments are specific to the BK channel, calculate 2D array of gating values if i == 0: #This is the forward rate constant for a two state channel gatingMatrix.append( pars.alphabeta * ca_array[None, :] / (ca_array[None, :] + pars.K * Vdepgating[:, None])) else: #this is backward rate constant for a two state channel gatingMatrix.append( pars.alphabeta / (1 + ca_array[None, :] / pars.K * Vdepgating[:, None])) #adding forward rate to backward rate gives “alpha+beta” which = 1/tau gatingMatrix[i] += gatingMatrix[0] chan = moose.HHChannel2D( '/library/' + chanparams.name) # two dimensional tabulated channel gating chan.Xpower = chanparams.Xpow chan.Ek = chanparams.Erev chan.Xindex = "VOLT_C1_INDEX" # critical for correctly using voltage and calcium xGate = moose.HHGate2D(chan.path + '/gateX') xGate.xminA = xGate.xminB = VMIN xGate.xmaxA = xGate.xmaxB = VMAX xGate.xdivsA = xGate.xdivsB = VDIVS xGate.yminA = xGate.yminB = CAMIN xGate.ymaxA = xGate.ymaxB = CAMAX xGate.ydivsA = xGate.ydivsB = CADIVS xGate.tableA = gatingMatrix[ 0] # assign gatingMatrix to tables, [0] is forw rate = ss/tau xGate.tableB = gatingMatrix[1] #[1] is 1/tau return chan
def wildcard_setup(): a = moose.Neutral('/alfa') b = moose.Compartment('/alfa/bravo') c = moose.HHChannel('/alfa/bravo/charlie') f = moose.HHChannel2D('/alfa/bravo/foxtrot') e = moose.Neutral('/alfa/echo') d = moose.DiffAmp('/alfa/echo/delta') p = moose.PulseGen('/alfa/echo/papa') e1 = moose.Pool('/alfa/bravo/charlie/echo') g = moose.HHChannel('%s/golf' % (e1.path)) f1 = moose.Neutral('/alfa/bravo/foxtail') c1 = moose.Neutral('/alfa/bravo/charlee') b.Rm = 2.0e6 c.Gbar = 1e-9 f.Gbar = 0.5e-6 p.delay[0] = 10e-3 d.gain = 3.0 g.Gbar = 1e-6
def BKchan_proto(model, chanpath, params): ZFbyRT= 2 * constants.Faraday / (constants.R * constants.celsius_to_kelvin(model.Temp)) v_array = np.linspace(model.VMIN, model.VMAX, model.VDIVS) ca_array = np.linspace(model.CAMIN, model.CAMAX, model.CADIVS) if model.VDIVS<=5 and model.CADIVS<=5: log.info("{}, {}", v_array, ca_array) gatingMatrix = [] for i,pars in enumerate(params.X): Vdepgating=pars.K*np.exp(pars.delta*ZFbyRT*v_array) if i == 0: gatingMatrix.append(pars.alphabeta*ca_array[None,:]/(ca_array[None,:]+pars.K*Vdepgating[:,None])) #table.tableVector2D=gatingMatrix else: gatingMatrix.append(pars.alphabeta/(1+ca_array[None,:]/pars.K*Vdepgating[:,None])) gatingMatrix[i] += gatingMatrix[0] #table.tableVector2D=gatingMatrix chan = moose.HHChannel2D(chanpath) chan.Xpower = params.channel.Xpow chan.Ek=params.channel.Erev chan.Xindex="VOLT_C1_INDEX" xGate = moose.HHGate2D(chan.path + '/gateX') xGate.xminA=xGate.xminB=model.VMIN xGate.xmaxA=xGate.xmaxB=model.VMAX xGate.xdivsA=xGate.xdivsB=model.VDIVS xGate.yminA=xGate.yminB=model.CAMIN xGate.ymaxA=xGate.ymaxB=model.CAMAX xGate.ydivsA=xGate.ydivsB=model.CADIVS xGate.tableA=gatingMatrix[0] xGate.tableB=gatingMatrix[1] if log.isEnabledFor(logging.INFO): log.info("{}", chan.path) for ii in np.arange(0, model.VDIVS,1000): log.info("V={}", model.VMIN+ii*(model.VMAX-model.VMIN)/(model.VDIVS-1)) for jj in np.arange(0,model.CADIVS,1000): log.info(" Ca={} A,B={},{}", model.CAMIN+jj*(model.CAMAX-model.CAMIN)/(model.CADIVS-1), xGate.tableA[ii][jj], xGate.tableB[ii][jj]) return chan
def connect_CaConc(compartment_list): context = moose.PyMooseBase.getContext() #### Connect the Ca pools and channels #### Ca channels should have an extra field called 'ion' defined and set in MOOSE. #### Ca dependent channels like KCa should have an extra field called 'ionDependency' defined and set in MOOSE. #### Am connecting these at the very end so that all channels and pools have been created for compartment in compartment_list: if context.exists(compartment.path + '/Ca_mit_conc'): # Ca Pool caconc = moose.CaConc(compartment.path + '/Ca_mit_conc') for child in compartment.getChildren(compartment.id): neutralwrap = moose.Neutral(child) if neutralwrap.className == 'HHChannel': channel = moose.HHChannel(child) ### If 'ion' field is not present, the Shell returns '0', cribs and prints out a message but it does not throw an exception if channel.getField('ion') == 'Ca': channel.connect('IkSrc', caconc, 'current') #print 'Connected ',channel.path if neutralwrap.className == 'HHChannel2D': channel = moose.HHChannel2D(child) ### If 'ionDependency' field is not present, the Shell returns '0', cribs and prints out a message but it does not throw an exception if channel.getField('ionDependency') == 'Ca': caconc.connect('concSrc', channel, 'concen')
def Ca_N_Chan(name): Ca_N = moose.HHChannel2D('/library/' + name) Ca_N.Ek = ECa Ca_N.Gbar = 300.0 * SOMA_A Ca_N.Gk = 0.0 Ca_N.Xpower = 2.0 Ca_N.Ypower = 1.0 Ca_N.Zpower = 1.0 Ca_N.Xindex = 'VOLT_INDEX' Ca_N.Yindex = 'VOLT_INDEX' Ca_N.Zindex = 'VOLT_C1_INDEX' Ca_N.instant = 4 xgate = moose.element(Ca_N.path + '/gateX') xgate.xminA = Vmin xgate.xmaxA = Vmax xgate.xdivsA = Vdivs # xgate.yminA = Camin # xgate.ymaxA = Camax # xgate.ydivsA = Cadivs xgate.xminB = Vmin xgate.xmaxB = Vmax xgate.xdivsB = Vdivs # xgate.yminB = Camin # xgate.ymaxB = Camax # xgate.ydivsB = Cadivs ygate = moose.element(Ca_N.path + '/gateY') ygate.xminA = Vmin ygate.xmaxA = Vmax ygate.xdivsA = Vdivs # ygate.yminA = Camin # ygate.ymaxA = Camax # ygate.ydivsA = Cadivs ygate.xminB = Vmin ygate.xmaxB = Vmax ygate.xdivsB = Vdivs # ygate.yminB = Camin # ygate.ymaxB = Camax # ygate.ydivsB = Cadivs zgate = moose.element(Ca_N.path + '/gateZ') zgate.xminA = Vmin zgate.xmaxA = Vmax zgate.xdivsA = Vdivs zgate.yminA = Camin zgate.ymaxA = Camax zgate.ydivsA = Cadivs zgate.xminB = Vmin zgate.xmaxB = Vmax zgate.xdivsB = Vdivs zgate.yminB = Camin zgate.ymaxB = Camax zgate.ydivsB = Cadivs cao = 2 z = 2 T = celsius + 273.15 ki = .001 q10 = 5 mmin = 0.2 hmin = 3 a0m = 0.03 zetam = 2 vhalfm = -14 gmm = 0.1 gcanbar = .0003e4 alph = 1.6e-4 * np.exp(-v * 1e3 / 48.4) beth = 1 / (np.exp((-v * 1e3 + 39.0) / 10.) + 1.) alpm = 0.1967 * (-1.0 * v * 1e3 + 19.88) / (np.exp( (-1.0 * v * 1e3 + 19.88) / 10.0) - 1.0) betm = 0.046 * np.exp(-v * 1e3 / 20.73) alpmt = np.exp(0.0378 * zetam * (v * 1e3 - vhalfm)) betmt = np.exp(0.0378 * zetam * gmm * (v * 1e3 - vhalfm)) qt = q10**((celsius - 25) / 10) a = alpm b = 1 / (a + betm) minf = a / (a + b) minf = a * b taum = betmt / (qt * a0m * (1 + alpmt)) taum[taum < mmin / qt] = mmin / qt tblA = np.zeros([Vdivs, 1]) tblB = np.zeros([Vdivs, 1]) for i in np.arange(1): tblA[:, i] = minf / taum tblB[:, i] = 1 / taum print(i, end='\r') xgate.tableA = tblA * 1e3 xgate.tableB = tblB * 1e3 qt = q10**((celsius - 25) / 10) a = alph b = 1 / (a + beth) hinf = a * b tauh = 80 * np.ones(len(hinf)) tauh[tauh < hmin] = hmin tblA = np.zeros([Vdivs, 1]) tblB = np.zeros([Vdivs, 1]) for i in np.arange(1): tblA[:, i] = hinf / tauh tblB[:, i] = 1 / tauh print(i, end='\r') ygate.tableA = tblA * 1e3 ygate.tableB = tblB * 1e3 ezfrt = np.exp(z * v * F / R / T) tblA = np.zeros([Vdivs, Cadivs]) tblB = np.zeros([Vdivs, Cadivs]) for i in np.arange(Cadivs): tblA[:, i] = ki / (ki + ca[i]) * v * (ca[i] / cao * ezfrt - 1) / (ezfrt - 1) / (v - ECa) print(i, end='\r') tblB = tblA * 0 + 1 zgate.tableA = tblA zgate.tableB = tblB addmsg4 = moose.Mstring(Ca_N.path + '/addmsg4') addmsg4.value = '../Ca_conc concOut . concen' addmsg2 = moose.Mstring(Ca_N.path + '/addmsg2') addmsg2.value = '. IkOut ../Ca_conc current' return Ca_N
def Ca_T_Chan(name): Ca_T = moose.HHChannel2D( '/library/' + name ) Ca_T.Ek = EK Ca_T.Gbar = 300.0*SOMA_A Ca_T.Gk = 0.0 Ca_T.Xpower = 2.0 # Ca_T.Ypower = 1.0 # Ca_T.Zpower = 1.0 Ca_T.Xindex = 'VOLT_INDEX' # Ca_T.Yindex = 'VOLT_INDEX' # Ca_T.Zindex = 'VOLT_C1_INDEX' xgate = moose.element( Ca_T.path + '/gateX' ) xgate.xminA = Vmin xgate.xmaxA = Vmax xgate.xdivsA = 0 xgate.yminA = Vmin xgate.ymaxA = Vmax xgate.ydivsA = Vdivs xgate.xminB = Vmin xgate.xmaxB = Vmax xgate.xdivsB = 0 xgate.yminB = Vmin xgate.ymaxB = Vmax xgate.ydivsB = Vdivs # ygate = moose.element( Ca_T.path + '/gateY' ) # ygate.xminA = 0 # ygate.xmaxA = 0 # ygate.xdivsA = 0 # ygate.yminA = Vmin # ygate.ymaxA = Vmax # ygate.ydivsA = Vdivs # ygate.xminB = 0 # ygate.xmaxB = 0 # ygate.xdivsB = 0 # ygate.yminB = Vmin # ygate.ymaxB = Vmax # ygate.ydivsB = Vdivs # zgate = moose.element( Ca_T.path + '/gateZ' ) # zgate.xminA = Vmin # zgate.xmaxA = Vmax # zgate.xdivsA = Vdivs # zgate.yminA = Camin # zgate.ymaxA = Camax # zgate.ydivsA = Cadivs # zgate.xminB = Vmin # zgate.xmaxB = Vmax # zgate.xdivsB = Vdivs # zgate.yminB = Camin # zgate.ymaxB = Camax # zgate.ydivsB = Cadivs cai = 50.e-6 cao = 2 q10 = 5 mmin=0.2 hmin=10 a0h =0.015 zetah = 3.5 vhalfh = -75 gmh=0.6 a0m =0.04 zetam = 2 vhalfm = -28 gmm=0.1 qt=q10**((celsius-25)/10) a = 0.2*(-1.0*v*1e3+19.26)/(np.exp((-1.0*v*1e3+19.26)/10.0)-1.0) b = 0.009*np.exp(-v*1e3/22.03) minf = a/(a+b) alpmt = np.exp(0.0378*zetam*(v*1e3-vhalfm)) betmt = np.exp(0.0378*zetam*gmm*(v*1e3-vhalfm)) mtau = betmt/(qt*a0m*(1+alpmt)) mtau[mtau<mmin]=mmin x = Vmin tblA = np.zeros([2,len(v)]) tblB = np.zeros([2,len(v)]) for i in np.arange(2): tblA[i] = minf/mtau*np.ones(len(v)) tblB[i] = 1/mtau*np.ones(len(v)) x = x + dV print(i, end='\r') xgate.tableA = tblA*1e3 xgate.tableB = tblB*1e3 # a = 1.e-6*np.exp(-v/16.26) # b = 1/(np.exp((-v+29.79)/10.)+1.) # hinf = a/(a+b) # alph = np.exp(0.0378*zetah*(v*1e3-vhalfh)) # beth = np.exp(0.0378*zetah*gmh*(v*1e3-vhalfh)) # htau = beth/(a0h*(1+alph)) # htau[htau<hmin]=hmin # ygate.tableA = hinf/htau*1e3 # ygate.tableB = 1/htau*1e3 # x = Vmin # tblA = np.zeros([len(v),len(ca)]) # tblB = np.zeros([len(v),len(ca)]) # for i in np.arange(len(v)): # tblA[i] = np.array([alp(x,y) for y in ca]) # tblB[i] = np.add(tblA[i],[bet(x, y) for y in ca])/tfactor # x = x + dV # print(i, end='\r') # # zgate.tableA = tblA*1e3 # zgate.tableB = tblB*1e3 addmsg4 = moose.Mstring( Ca_T.path + '/addmsg4' ) addmsg4.value = '../Ca_conc concOut . concen' return Ca_T
def set_compartment_param(self, compartment, name, value, mechanismname): """ Set the param for the compartment depending on name and mechanismname. """ if name == 'CM': compartment.Cm = value * math.pi * compartment.diameter * compartment.length elif name == 'RM': compartment.Rm = value / (math.pi * compartment.diameter * compartment.length) elif name == 'RA': compartment.Ra = value * compartment.length / ( math.pi * (compartment.diameter / 2.0)**2) elif name == 'Em': compartment.Em = value elif name == 'initVm': compartment.initVm = value elif name == 'inject': # this reader converts to SI _logger.info("Comparment %s inject %s A." % (compartment.name, value)) compartment.inject = value elif name == 'v_reset': compartment.vReset = value # compartment is a moose.LIF instance (intfire) elif name == 'threshold': compartment.thresh = value # compartment is a moose.LIF instance (intfire) elif name == 't_refrac': compartment.refractoryPeriod = value # compartment is a moose.LIF instance (intfire) elif name == 'g_refrac': _logger.info("SORRY, current moose.LIF doesn't support g_refrac.") elif mechanismname is 'synapse': # synapse being added to the compartment ## these are potential locations, we do not actually make synapses, ## unless the user has explicitly asked for it if self.createPotentialSynapses: syn_name = value if not moose.exists(compartment.path + '/' + syn_name): make_new_synapse(syn_name, compartment, syn_name, self.nml_params) ## I assume below that compartment name has _segid at its end segid = compartment.name.split('_')[ -1] # get segment id from compartment name self.segDict[segid][5].append(value) elif mechanismname is 'spikegen': # spikegen being added to the compartment ## these are potential locations, we do not actually make the spikegens. ## spikegens for different synapses can have different thresholds, ## hence include synapse_type in its name ## value contains name of synapse i.e. synapse_type #spikegen = moose.SpikeGen(compartment.path+'/'+value+'_spikegen') #moose.connect(compartment,"VmSrc",spikegen,"Vm") pass ## previous were mechanism that don't need a ChannelML definition ## including integrate_and_fire (I ignore the ChannelML definition) ## thus integrate_and_fire mechanism default values cannot be used ## i.e. nothing needed in /library, but below mechanisms need. elif mechanismname is not None: ## if mechanism is not present in compartment, deep copy from library ## all mechanisms have been loaded into the library earlier if not moose.exists(compartment.path + '/' + mechanismname): neutralObj = moose.element( "/library/" + mechanismname) # gives error if not present if 'CaConc' == neutralObj.className: # Ion concentration pool libcaconc = moose.CaConc("/library/" + mechanismname) ## deep copies the library caconc under the compartment caconc = moose.copy(libcaconc, compartment, mechanismname) caconc = moose.CaConc(caconc) ## CaConc connections are made later using connect_CaConc() ## Later, when calling connect_CaConc, ## B is set for caconc based on thickness of Ca shell and compartment l and dia ## OR based on the Mstring phi under CaConc path. channel = None elif 'HHChannel2D' == neutralObj.className: ## HHChannel2D libchannel = moose.HHChannel2D("/library/" + mechanismname) ## deep copies the library channel under the compartment channel = moose.copy(libchannel, compartment, mechanismname) channel = moose.HHChannel2D(channel) moose.connect(channel, 'channel', compartment, 'channel') elif 'HHChannel' == neutralObj.className: ## HHChannel libchannel = moose.HHChannel("/library/" + mechanismname) ## deep copies the library channel under the compartment channel = moose.copy(libchannel, compartment, mechanismname) channel = moose.HHChannel(channel) moose.connect(channel, 'channel', compartment, 'channel') ## if mechanism is present in compartment, just wrap it else: neutralObj = moose.Neutral(compartment.path + '/' + mechanismname) if 'CaConc' == neutralObj.className: # Ion concentration pool caconc = moose.CaConc( compartment.path + '/' + mechanismname) # wraps existing channel channel = None elif 'HHChannel2D' == neutralObj.className: ## HHChannel2D channel = moose.HHChannel2D( compartment.path + '/' + mechanismname) # wraps existing channel elif 'HHChannel' == neutralObj.className: ## HHChannel channel = moose.HHChannel( compartment.path + '/' + mechanismname) # wraps existing channel if name == 'Gbar': if channel is None: # if CaConc, neuroConstruct uses gbar for thickness or phi ## If child Mstring 'phi' is present, set gbar as phi ## BUT, value has been multiplied by Gfactor as a Gbar, ## SI or physiological not known here, ## ignoring Gbar for CaConc, instead of passing units here child = moose_utils.get_child_Mstring(caconc, 'phi') if child is not None: #child.value = value pass else: #caconc.thick = value pass else: # if ion channel, usual Gbar channel.Gbar = value * math.pi * compartment.diameter * compartment.length elif name == 'Ek': channel.Ek = value elif name == 'thick': # thick seems to be NEURON's extension to NeuroML level 2. caconc.thick = value ## JUST THIS WILL NOT DO - HAVE TO SET B based on this thick! ## Later, when calling connect_CaConc, ## B is set for caconc based on thickness of Ca shell and compartment l and dia. ## OR based on the Mstring phi under CaConc path. if neuroml_utils.neuroml_debug: _logger.info("Setting %s for comparment %s to %s" % (name, compartment.path, value))
def Ca_L_Chan(name): Ca_L = moose.HHChannel2D('/library/' + name) Ca_L.Ek = ECa Ca_L.Gbar = 300.0 * SOMA_A Ca_L.Gk = 0.0 Ca_L.Xpower = 2.0 Ca_L.Ypower = 0.0 Ca_L.Zpower = 1.0 Ca_L.Xindex = 'VOLT_INDEX' # Ca_L.Yindex = 'C1_INDEX' Ca_L.Zindex = 'VOLT_C1_INDEX' Ca_L.instant = 4 xgate = moose.element(Ca_L.path + '/gateX') xgate.xminA = Vmin xgate.xmaxA = Vmax xgate.xdivsA = Vdivs # xgate.yminA = Camin # xgate.ymaxA = Camax # xgate.ydivsA = Cadivs xgate.xminB = Vmin xgate.xmaxB = Vmax xgate.xdivsB = Vdivs # xgate.yminB = Camin # xgate.ymaxB = Camax # xgate.ydivsB = Cadivs zgate = moose.element(Ca_L.path + '/gateZ') zgate.xminA = Vmin zgate.xmaxA = Vmax zgate.xdivsA = Vdivs zgate.yminA = Camin zgate.ymaxA = Camax zgate.ydivsA = Cadivs zgate.xminB = Vmin zgate.xmaxB = Vmax zgate.xdivsB = Vdivs zgate.yminB = Camin zgate.ymaxB = Camax zgate.ydivsB = Cadivs cao = 2 z = 2 T = celsius + 273.15 ki = .001 cai = 50.e-6 cao = 2 q10 = 5 mmin = 0.2 tfa = 1 a0m = 0.1 zetam = 2 vhalfm = 4 gmm = 0.1 gcalbar = .003e4 qt = q10**((celsius - 25) / 10) a = 15.69 * (-1.0 * v * 1e3 + 81.5) / (np.exp( (-1.0 * v * 1e3 + 81.5) / 10.0) - 1.0) b = 1 / (a + 0.29 * np.exp(-v * 1e3 / 10.86)) minf = a * b alpmt = np.exp(0.0378 * zetam * (v * 1e3 - vhalfm)) betmt = np.exp(0.0378 * zetam * gmm * (v * 1e3 - vhalfm)) tau = betmt / (qt * a0m * (1 + alpmt)) tau[tau < mmin / qt] = mmin / qt tblA = np.zeros([Vdivs, 1]) tblB = np.zeros([Vdivs, 1]) for i in np.arange(1): tblA[:, i] = minf / tau tblB[:, i] = 1 / tau print(i, end='\r') xgate.tableA = tblA * 1e3 xgate.tableB = tblB * 1e3 ezfrt = np.exp(z * v * F / R / T) tblA = np.zeros([Vdivs, Cadivs]) tblB = np.zeros([Vdivs, Cadivs]) for i in np.arange(Cadivs): tblA[:, i] = ki / (ki + ca[i]) * v * (ca[i] / cao * ezfrt - 1) / (ezfrt - 1) / (v - ECa) print(i, end='\r') tblB = tblA * 0 + 1 zgate.tableA = tblA zgate.tableB = tblB addmsg4 = moose.Mstring(Ca_L.path + '/addmsg4') addmsg4.value = '../Ca_conc concOut . concen' addmsg2 = moose.Mstring(Ca_L.path + '/addmsg2') addmsg2.value = '. IkOut ../Ca_conc current' return Ca_L
def set_compartment_param(self, compartment, name, value, mechName): """ Set the param for the compartment depending on name and mechName. """ if name == 'CM': compartment.Cm = value * math.pi * compartment.diameter * compartment.length elif name == 'RM': compartment.Rm = value / (math.pi * compartment.diameter * compartment.length) elif name == 'RA': compartment.Ra = value * compartment.length / \ (math.pi*(compartment.diameter/2.0)**2) elif name == 'Em': compartment.Em = value elif name == 'initVm': compartment.initVm = value elif name == 'inject': msg = " {0} inject {1} A.".format(compartment.name, value) debug.printDebug("INFO", msg) compartment.inject = value elif mechName is 'synapse': # synapse being added to the compartment # these are potential locations, we do not actually make synapses. # I assume below that compartment name has _segid at its end # get segment id from compartment name segid = moose_methods.getCompartmentId(compartment.name) self.segDict[segid][5].append(value) # spikegen being added to the compartment elif mechName is 'spikegen': # these are potential locations, we do not actually make the # spikegens. spikegens for different synapses can have different # thresholds, hence include synapse_type in its name value contains # name of synapse i.e. synapse_type #spikegen = moose.SpikeGen(compartment.path+'/'+value+'_spikegen') #moose.connect(compartment,"VmSrc",spikegen,"Vm") pass elif mechName is not None: # if mechanism is not present in compartment, deep copy from library if not moose.exists(compartment.path + '/' + mechName): # if channel does not exist in library load it from xml file if not moose.exists(self.libraryPath + "/" + mechName): cmlR = ChannelML(self.nml_params) model_filename = mechName + '.xml' model_path = neuroml_utils.find_first_file( model_filename, self.model_dir) if model_path is not None: cmlR.readChannelMLFromFile(model_path) else: msg = 'Mechanism {0}: files {1} not found under {2}'\ .format( mechName , model_filename , self.model_dir ) debug.printDebug("ERROR", msg, frame=inspect.currentframe()) sys.exit(0) neutralObj = moose.Neutral(self.libraryPath + "/" + mechName) # Ion concentration pool if 'CaConc' == neutralObj.className: libcaconc = moose.CaConc(self.libraryPath + "/" + mechName) # deep copies the library caconc under the compartment caconc = moose.copy(libcaconc, compartment, mechName) caconc = moose.CaConc(caconc) # CaConc connections are made later using connect_CaConc() # Later, when calling connect_CaConc, B is set for caconc # based on thickness of Ca shell and compartment l and dia # OR based on the Mstring phi under CaConc path. channel = None elif 'HHChannel2D' == neutralObj.className: ## HHChannel2D libchannel = moose.HHChannel2D(self.libraryPath + "/" + mechName) ## deep copies the library channel under the compartment channel = moose.copy(libchannel, compartment, mechName) channel = moose.HHChannel2D(channel) moose.connect(channel, 'channel', compartment, 'channel') elif 'HHChannel' == neutralObj.className: ## HHChannel libchannel = moose.HHChannel(self.libraryPath + "/" + mechName) # deep copies the library channel under the compartment channel = moose.copy(libchannel, compartment, mechName) channel = moose.HHChannel(channel) moose.connect(channel, 'channel', compartment, 'channel') # if mechanism is present in compartment, just wrap it else: neutralObj = moose.Neutral(compartment.path + '/' + mechName) # Ion concentration pool if 'CaConc' == neutralObj.className: # wraps existing channel caconc = moose.CaConc(compartment.path + '/' + mechName) channel = None elif 'HHChannel2D' == neutralObj.className: ## HHChannel2D # wraps existing channel channel = moose.HHChannel2D(compartment.path + '/' + mechName) elif 'HHChannel' == neutralObj.className: ## HHChannel # wraps existing channel channel = moose.HHChannel(compartment.path + '/' + mechName) if name == 'Gbar': # if CaConc, neuroConstruct uses gbar for thickness or phi if channel is None: # If child Mstring 'phi' is present, set gbar as phi BUT, # value has been multiplied by Gfactor as a Gbar, SI or # physiological not known here, ignoring Gbar for CaConc, # instead of passing units here child = moose_utils.get_child_Mstring(caconc, 'phi') if child is not None: #child.value = value pass else: #caconc.thick = value pass else: # if ion channel, usual Gbar channel.Gbar = value * math.pi * compartment.diameter \ * compartment.length elif name == 'Ek': channel.Ek = value # thick seems to be NEURON's extension to NeuroML level 2. elif name == 'thick': # JUST THIS WILL NOT DO - HAVE TO SET B based on this thick! caconc.thick = value # Later, when calling connect_CaConc, B is set for caconc based # on thickness of Ca shell and compartment l and dia. OR based # on the Mstring phi under CaConc path. if neuroml_utils.neuroml_debug: msg = "Setting {0} for {1} value {2}".format( name, compartment.path, value) debug.printDebug("DEBUG", msg, frame=inspect.currentframe())
def readChannelML(self, channelElement, params={}, units="SI units"): ## I first calculate all functions assuming a consistent system of units. ## While filling in the A and B tables, I just convert to SI. ## Also convert gmax and Erev. if 'Physiological Units' in units: # see pg 219 (sec 13.2) of Book of Genesis Vfactor = 1e-3 # V from mV Tfactor = 1e-3 # s from ms Gfactor = 1e1 # S/m^2 from mS/cm^2 concfactor = 1e6 # Mol = mol/m^-3 from mol/cm^-3 elif 'SI Units' in units: Vfactor = 1.0 Tfactor = 1.0 Gfactor = 1.0 concfactor = 1.0 else: raise RuntimeError("Wrong units %s. Existing" % units) if not moose.exists('/library'): moose.Neutral('/library') channel_name = channelElement.attrib['name'] if utils.neuroml_debug: pu.info("Loading channel %s into /library" % channel_name) IVrelation = channelElement.find('./{' + self.cml + '}current_voltage_relation') intfire = IVrelation.find('./{' + self.cml + '}integrate_and_fire') if intfire is not None: ## Below params need to be set while making an LIF compartment moosechannel = moose.Neutral('/library/' + channel_name) moosechannelval = moose.Mstring(moosechannel.path + '/vReset') moosechannelval.value = str( float(intfire.attrib['v_reset']) * Vfactor) moosechannelval = moose.Mstring(moosechannel.path + '/thresh') moosechannelval.value = str( float(intfire.attrib['threshold']) * Vfactor) moosechannelval = moose.Mstring(moosechannel.path + '/refracT') moosechannelval.value = str( float(intfire.attrib['t_refrac']) * Tfactor) ## refracG is currently not supported by moose.LIF ## Confirm if g_refrac is a conductance density or not? ## assuming g_refrac is a conductance density below moosechannelval = moose.Mstring(moosechannel.path + '/refracG') moosechannelval.value = str( float(intfire.attrib['g_refrac']) * Gfactor) ## create an Mstring saying this is an integrate_and_fire mechanism moosechannelval = moose.Mstring(moosechannel.path + '/integrate_and_fire') moosechannelval.value = 'True' return concdep = IVrelation.find('./{' + self.cml + '}conc_dependence') if concdep is None: moosechannel = moose.HHChannel('/library/' + channel_name) else: moosechannel = moose.HHChannel2D('/library/' + channel_name) if IVrelation.attrib['cond_law'] == "ohmic": moosechannel.Gbar = float( IVrelation.attrib['default_gmax']) * Gfactor moosechannel.Ek = float( IVrelation.attrib['default_erev']) * Vfactor moosechannelIon = moose.Mstring(moosechannel.path + '/ion') moosechannelIon.value = IVrelation.attrib['ion'] if concdep is not None: moosechannelIonDependency = moose.Mstring(moosechannel.path + '/ionDependency') moosechannelIonDependency.value = concdep.attrib['ion'] nernstnote = IVrelation.find('./{' + utils.meta_ns + '}notes') if nernstnote is not None: ## the text in nernstnote is "Nernst,Cout=<float>,z=<int>" nernst_params = nernstnote.text.split(',') if nernst_params[0] == 'Nernst': nernstMstring = moose.Mstring(moosechannel.path + '/nernst_str') nernstMstring.value = str( float(nernst_params[1].split('=')[1]) * concfactor ) + \ ',' + str( int(nernst_params[2].split('=')[1]) ) gates = IVrelation.findall('./{' + self.cml + '}gate') if len(gates) > 3: pu.fatal( "Sorry! Maximum x, y, and z (three) gates are possible in MOOSE/Genesis" ) sys.exit() gate_full_name = [ 'gateX', 'gateY', 'gateZ' ] # These are the names that MOOSE uses to create gates. ## if impl_prefs tag is present change VMIN, VMAX and NDIVS impl_prefs = channelElement.find('./{' + self.cml + '}impl_prefs') if impl_prefs is not None: table_settings = impl_prefs.find('./{' + self.cml + '}table_settings') ## some problem here... disable VMIN_here = float(table_settings.attrib['min_v']) VMAX_here = float(table_settings.attrib['max_v']) NDIVS_here = int(table_settings.attrib['table_divisions']) dv_here = (VMAX_here - VMIN_here) / NDIVS_here else: ## default VMIN, VMAX and dv are in SI ## convert them to current calculation units used by channel definition ## while loading into tables, convert them back to SI VMIN_here = utils.VMIN / Vfactor VMAX_here = utils.VMAX / Vfactor NDIVS_here = utils.NDIVS dv_here = utils.dv / Vfactor offset = IVrelation.find('./{' + self.cml + '}offset') if offset is None: vNegOffset = 0.0 else: vNegOffset = float(offset.attrib['value']) self.parameters = [] for parameter in channelElement.findall('.//{' + self.cml + '}parameter'): self.parameters.append( (parameter.attrib['name'], float(parameter.attrib['value']))) for num, gate in enumerate(gates): # if no q10settings tag, the q10factor remains 1.0 # if present but no gate attribute, then set q10factor # if there is a gate attribute, then set it only if gate attrib matches gate name self.q10factor = 1.0 self.gate_name = gate.attrib['name'] for q10settings in IVrelation.findall('./{' + self.cml + '}q10_settings'): ## self.temperature from neuro.utils if 'gate' in q10settings.attrib: if q10settings.attrib['gate'] == self.gate_name: self.setQ10(q10settings) break else: self.setQ10(q10settings) ############### HHChannel2D crashing on setting Xpower! #### temperamental! If you print something before, it gives cannot creategate from copied channel, else crashes ## Setting power first. This is necessary because it also ## initializes the gate's internal data structures as a side ## effect. Alternatively, gates can be initialized explicitly ## by calling HHChannel.createGate(). gate_power = float(gate.get('instances')) if num == 0: moosechannel.Xpower = gate_power if concdep is not None: moosechannel.Xindex = "VOLT_C1_INDEX" elif num == 1: moosechannel.Ypower = gate_power if concdep is not None: moosechannel.Yindex = "VOLT_C1_INDEX" elif num == 2: moosechannel.Zpower = gate_power if concdep is not None: moosechannel.Zindex = "VOLT_C1_INDEX" ## Getting handle to gate using the gate's path. gate_path = moosechannel.path + '/' + gate_full_name[num] if concdep is None: if not moose.exists(gate_path): moosegate = moose.HHGate(gate_path) else: moosegate = moose.element(gate_path) ## set SI values inside MOOSE moosegate.min = VMIN_here * Vfactor moosegate.max = VMAX_here * Vfactor moosegate.divs = NDIVS_here ## V.IMP to get smooth curves, else even with 3000 divisions ## there are sudden transitions. moosegate.useInterpolation = True else: moosegate = moose.HHGate2D(gate_path) ##### If alpha and beta functions exist, make them here for transition in gate.findall('./{' + self.cml + '}transition'): ## make python functions with names of transitions... fn_name = transition.attrib['name'] ## I assume that transitions if present are called alpha and beta ## for forward and backward transitions... if fn_name in ['alpha', 'beta']: self.make_cml_function(transition, fn_name, concdep) else: pu.fatal("Unsupported transition %s" % fn_name) sys.exit() time_course = gate.find('./{' + self.cml + '}time_course') ## tau is divided by self.q10factor in make_function() ## thus, it gets divided irrespective of <time_course> tag present or not. if time_course is not None: self.make_cml_function(time_course, 'tau', concdep) steady_state = gate.find('./{' + self.cml + '}steady_state') if steady_state is not None: self.make_cml_function(steady_state, 'inf', concdep) if concdep is None: ca_name = '' # no Ca dependence else: ca_name = ',' + concdep.attrib[ 'variable_name'] # Ca dependence ## Create tau() and inf() if not present, from alpha() and beta() for fn_element,fn_name,fn_expr in [(time_course,'tau',"1/(alpha+beta)"),\ (steady_state,'inf',"alpha/(alpha+beta)")]: ## put in args for alpha and beta, could be v and Ca dep. expr_string = fn_expr.replace('alpha', 'self.alpha(v' + ca_name + ')') expr_string = expr_string.replace( 'beta', 'self.beta(v' + ca_name + ')') ## if time_course/steady_state are not present, ## then alpha annd beta transition elements should be present, and fns created. if fn_element is None: self.make_function(fn_name, 'generic', expr_string=expr_string, concdep=concdep) ## non Ca dependent channel if concdep is None: ## while calculating, use the units used in xml defn, ## while filling in table, I convert to SI units. v0 = VMIN_here - vNegOffset n_entries = NDIVS_here + 1 tableA = [0.0] * n_entries tableB = [0.0] * n_entries for i in range(n_entries): v = v0 + i * dv_here inf = self.inf(v) tau = self.tau(v) ## convert to SI before writing to table ## qfactor is already in inf and tau tableA[i] = inf / tau / Tfactor tableB[i] = 1.0 / tau / Tfactor moosegate.tableA = tableA moosegate.tableB = tableB ## Ca dependent channel else: ## UNITS: while calculating, use the units used in xml defn, ## while filling in table, I convert to SI units. ## Note here Ca units do not enter, but ## units of CaMIN, CaMAX and ca_conc in fn expr should match. v = VMIN_here - vNegOffset CaMIN = float(concdep.attrib['min_conc']) CaMAX = float(concdep.attrib['max_conc']) CaNDIVS = 100 dCa = (CaMAX - CaMIN) / CaNDIVS ## CAREFUL!: tableA = [[0.0]*(CaNDIVS+1)]*(NDIVS_here+1) will not work! ## * does a shallow copy, same list will get repeated 200 times! ## Thus setting tableA[35][1] = 5.0 will set all rows, 1st col to 5.0!!!! tableA = [[0.0] * (CaNDIVS + 1) for i in range(NDIVS_here + 1)] tableB = [[0.0] * (CaNDIVS + 1) for i in range(NDIVS_here + 1)] for i in range(NDIVS_here + 1): Ca = CaMIN for j in range(CaNDIVS + 1): inf = self.inf(v, Ca) tau = self.tau(v, Ca) ## convert to SI (Tfactor) before writing to table ## qfactor is already in inf and tau tableA[i][j] = inf / tau / Tfactor tableB[i][j] = 1.0 / tau / Tfactor Ca += dCa v += dv_here ## Presently HHGate2D doesn't allow the setting of tables as 2D vectors directly moosegate.tableA = tableA moosegate.tableB = tableB ## set SI values inside MOOSE moosegate.xminA = VMIN_here * Vfactor moosegate.xmaxA = VMAX_here * Vfactor moosegate.xdivsA = NDIVS_here #moosegate.dxA = dv_here*Vfactor moosegate.yminA = CaMIN * concfactor moosegate.ymaxA = CaMAX * concfactor moosegate.ydivsA = CaNDIVS #moosegate.dyB = dCa*concfactor ## set SI values inside MOOSE moosegate.xminB = VMIN_here * Vfactor moosegate.xmaxB = VMAX_here * Vfactor moosegate.xdivsB = NDIVS_here #moosegate.dxB = dv_here*Vfactor moosegate.yminB = CaMIN * concfactor moosegate.ymaxB = CaMAX * concfactor moosegate.ydivsB = CaNDIVS
def Ca_T_Chan(name): Ca_T = moose.HHChannel2D('/library/' + name) Ca_T.Ek = ECa Ca_T.Gbar = 300.0 * SOMA_A Ca_T.Gk = 0.0 Ca_T.Xpower = 2.0 Ca_T.Ypower = 1.0 Ca_T.Zpower = 1.0 Ca_T.Xindex = 'VOLT_INDEX' Ca_T.Yindex = 'VOLT_INDEX' Ca_T.Zindex = 'VOLT_C1_INDEX' Ca_T.instant = 4 xgate = moose.element(Ca_T.path + '/gateX') xgate.xminA = Vmin xgate.xmaxA = Vmax xgate.xdivsA = Vdivs # xgate.yminA = Camin # xgate.ymaxA = Camax # xgate.ydivsA = Cadivs xgate.xminB = Vmin xgate.xmaxB = Vmax xgate.xdivsB = Vdivs # xgate.yminB = Camin # xgate.ymaxB = Camax # xgate.ydivsB = Cadivs ygate = moose.element(Ca_T.path + '/gateY') ygate.xminA = Vmin ygate.xmaxA = Vmax ygate.xdivsA = Vdivs # ygate.yminA = Camin # ygate.ymaxA = Camax # ygate.ydivsA = Cadivs ygate.xminB = Vmin ygate.xmaxB = Vmax ygate.xdivsB = Vdivs # ygate.yminB = Camin # ygate.ymaxB = Camax # ygate.ydivsB = Cadivs zgate = moose.element(Ca_T.path + '/gateZ') zgate.xminA = Vmin zgate.xmaxA = Vmax zgate.xdivsA = Vdivs zgate.yminA = Camin zgate.ymaxA = Camax zgate.ydivsA = Cadivs zgate.xminB = Vmin zgate.xmaxB = Vmax zgate.xdivsB = Vdivs zgate.yminB = Camin zgate.ymaxB = Camax zgate.ydivsB = Cadivs cao = 2 q10 = 5 mmin = 0.2 hmin = 10 a0h = 0.015 zetah = 3.5 vhalfh = -75 gmh = 0.6 a0m = 0.04 zetam = 2 vhalfm = -28 gmm = 0.1 z = 2 T = celsius + 273.15 gcatbar = .003e4 qt = q10**((celsius - 25) / 10) a = 0.2 * (-1.0 * v * 1e3 + 19.26) / (np.exp( (-1.0 * v * 1e3 + 19.26) / 10.0) - 1.0) b = 0.009 * np.exp(-v * 1e3 / 22.03) minf = a / (a + b) alpmt = np.exp(0.0378 * zetam * (v * 1e3 - vhalfm)) betmt = np.exp(0.0378 * zetam * gmm * (v * 1e3 - vhalfm)) mtau = betmt / (qt * a0m * (1 + alpmt)) mtau[mtau < mmin] = mmin tblA = np.zeros([Vdivs, 1]) tblB = np.zeros([Vdivs, 1]) for i in np.arange(1): tblA[:, i] = minf / mtau tblB[:, i] = 1 / mtau print(i, end='\r') xgate.tableA = tblA * 1e3 xgate.tableB = tblB * 1e3 qt = q10**((celsius - 25) / 10) a = 1.e-6 * np.exp(-v * 1e3 / 16.26) b = 1 / (np.exp((-v * 1e3 + 29.79) / 10.) + 1.) hinf = a / (a + b) alph = np.exp(0.0378 * zetah * (v * 1e3 - vhalfh)) beth = np.exp(0.0378 * zetah * gmh * (v * 1e3 - vhalfh)) htau = beth / (a0h * (1 + alph)) htau[htau < hmin] = hmin tblA = np.zeros([Vdivs, 1]) tblB = np.zeros([Vdivs, 1]) for i in np.arange(1): tblA[:, i] = hinf / htau tblB[:, i] = 1 / htau print(i, end='\r') ygate.tableA = tblA * 1e3 ygate.tableB = tblB * 1e3 ezfrt = np.exp(z * v * F / R / T) tblA = np.zeros([Vdivs, Cadivs]) tblB = np.zeros([Vdivs, Cadivs]) for i in np.arange(Cadivs): tblA[:, i] = v * (ca[i] / cao * ezfrt - 1) / (ezfrt - 1) / (v - ECa) print(i, end='\r') tblB = tblA * 0 + 1 zgate.tableA = tblA zgate.tableB = tblB addmsg4 = moose.Mstring(Ca_T.path + '/addmsg4') addmsg4.value = '../Ca_conc concOut . concen' addmsg2 = moose.Mstring(Ca_T.path + '/addmsg2') addmsg2.value = '. IkOut ../Ca_conc current' return Ca_T
def simp_Chan(name): simp = moose.HHChannel2D('/library/' + name) simp.Ek = EK simp.Gbar = 300.0 * SOMA_A simp.Gk = 0.0 simp.Xpower = 1.0 simp.Ypower = 0.0 simp.Zpower = 1.0 simp.Xindex = 'VOLT_INDEX' # simp.Yindex = 'VOLT_INDEX' simp.Zindex = 'VOLT_C1_INDEX' simp.instant = 2 xgate = moose.element(simp.path + '/gateX') xgate.xminA = Vmin xgate.xmaxA = Vmax xgate.xdivsA = Vdivs xgate.yminA = Vmin xgate.ymaxA = Vmax xgate.ydivsA = Vdivs xgate.xminB = Vmin xgate.xmaxB = Vmax xgate.xdivsB = Vdivs xgate.yminB = Vmin xgate.ymaxB = Vmax xgate.ydivsB = Vdivs # zgate = moose.element( simp.path + '/gateZ' ) # zgate.xminA = Vmin # zgate.xmaxA = Vmax # zgate.xdivsA = Vdivs # zgate.yminA = Camin # zgate.ymaxA = Camax # zgate.ydivsA = Cadivs # zgate.xminB = Vmin # zgate.xmaxB = Vmax # zgate.xdivsB = Vdivs # zgate.yminB = Camin # zgate.ymaxB = Camax # zgate.ydivsB = Cadivs cai = 0.05e-3 cao = 2 q10 = 5 mmin = 0.2 hmin = 10 a0h = 0.015 zetah = 3.5 vhalfh = -75 gmh = 0.6 a0m = 0.04 zetam = 2 vhalfm = -28 gmm = 0.1 qt = q10**((celsius - 25) / 10) a = 0.2 * (-1.0 * v * 1e3 + 19.26) / (np.exp( (-1.0 * v * 1e3 + 19.26) / 10.0) - 1.0) b = 0.009 * np.exp(-v * 1e3 / 22.03) minf = a / (a + b) alpmt = np.exp(0.0378 * zetam * (v * 1e3 - vhalfm)) betmt = np.exp(0.0378 * zetam * gmm * (v * 1e3 - vhalfm)) mtau = betmt / (qt * a0m * (1 + alpmt)) mtau[mtau < mmin] = mmin tblA = np.reshape(np.tile(minf / mtau, xgate.ydivsA), (xgate.xdivsA, xgate.ydivsA)) tblB = np.reshape(np.tile(1 / mtau, xgate.ydivsA), (xgate.xdivsA, xgate.ydivsA)) xgate.tableA = tblA * 1e3 xgate.tableB = tblB * 1e3 # x = Vmin # tblA = np.zeros([len(v),len(ca)]) # tblB = np.zeros([len(v),len(ca)]) # for i in np.arange(len(v)): # tblA[i] = np.array([alp(x,y) for y in ca]) # tblB[i] = np.add(tblA[i],[bet(x, y) for y in ca])/tfactor # x = x + dV # print(i, end='\r') # # zgate.tableA = tblA*1e3 # zgate.tableB = tblB*1e3 addmsg4 = moose.Mstring(simp.path + '/addmsg4') addmsg4.value = '../Ca_conc concOut . concen' return simp
def simp_Chan(name): simp = moose.HHChannel2D('/library/' + name) simp.Ek = ECa simp.Gbar = 300.0 * SOMA_A simp.Gk = 0.0 simp.Xpower = 0.0 simp.Ypower = 0.0 simp.Zpower = 1.0 # simp.Xindex = 'VOLT_INDEX' # simp.Yindex = 'VOLT_INDEX' simp.Zindex = 'VOLT_C1_INDEX' simp.instant = 4 # xgate = moose.element( simp.path + '/gateX' ) # xgate.xminA = Vmin # xgate.xmaxA = Vmax # xgate.xdivsA = 0 # xgate.yminA = Vmin # xgate.ymaxA = Vmax # xgate.ydivsA = Vdivs # xgate.xminB = Vmin # xgate.xmaxB = Vmax # xgate.xdivsB = 0 # xgate.yminB = Vmin # xgate.ymaxB = Vmax # xgate.ydivsB = Vdivs # xgate = moose.element( simp.path + '/gateX' ) # xgate.xminA = Vmin # xgate.xmaxA = Vmax # xgate.xdivsA = 0 # xgate.yminA = Vmin # xgate.ymaxA = Vmax # xgate.ydivsA = Vdivs # xgate.xminB = Vmin # xgate.xmaxB = Vmax # xgate.xdivsB = 0 # xgate.yminB = Vmin # xgate.ymaxB = Vmax # xgate.ydivsB = Vdivs zgate = moose.element(simp.path + '/gateZ') zgate.xminA = Vmin zgate.xmaxA = Vmax zgate.xdivsA = Vdivs zgate.yminA = Camin zgate.ymaxA = Camax zgate.ydivsA = Cadivs zgate.xminB = Vmin zgate.xmaxB = Vmax zgate.xdivsB = Vdivs zgate.yminB = Camin zgate.ymaxB = Camax zgate.ydivsB = Cadivs # q10 = 5 # mmin=0.2 # hmin=10 # a0h =0.015 # zetah = 3.5 # vhalfh = -75 # gmh=0.6 # a0m =0.04 # zetam = 2 # vhalfm = -28 # gmm=0.1 # # qt=q10**((celsius-25)/10) # # a = 0.2*(-1.0*v*1e3+19.26)/(np.exp((-1.0*v*1e3+19.26)/10.0)-1.0) # b = 0.009*np.exp(-v*1e3/22.03) # minf = a/(a+b) # alpmt = np.exp(0.0378*zetam*(v*1e3-vhalfm)) # betmt = np.exp(0.0378*zetam*gmm*(v*1e3-vhalfm)) # mtau = betmt/(qt*a0m*(1+alpmt)) # mtau[mtau<mmin]=mmin # tblA = np.zeros([xgate.ydivsA, 2]) # tblB = np.zeros([xgate.ydivsB, 2]) # for i in np.arange(2): # tblA[:,i] = minf/mtau # tblB[:,i] = 1/minf # print(i, end='\r') # print('X setup') # tblA = np.transpose(minf/mtau) # tblB = np.transpose(1/mtau) # tblA = np.reshape(np.tile(minf/mtau,xgate.ydivsA),(xgate.xdivsA,xgate.ydivsA)) # tblB = np.reshape(np.tile(1/mtau,xgate.ydivsA),(xgate.xdivsA,xgate.ydivsA)) # xgate.tableA = tblA*1e3 # xgate.tableB = tblB*1e3 z = 2 T = celsius + 273.15 cao = 2 ezfrt = np.exp(z * v * F / R / T) tblA = np.zeros([zgate.ydivsA, zgate.xdivsA]) tblB = np.zeros([zgate.ydivsB, zgate.xdivsB]) for i in np.arange(zgate.ydivsA): tblA[i] = v * (ca[i] / cao * ezfrt - 1) / (ezfrt - 1) / (v - ECa) print(i, end='\r') tblB = tblA * 0 + 1 zgate.tableA = tblA zgate.tableB = tblB addmsg4 = moose.Mstring(simp.path + '/addmsg4') addmsg4.value = '../Ca_conc concOut . concen' addmsg2 = moose.Mstring(simp.path + '/addmsg2') addmsg2.value = '. IkOut ../Ca_conc current' return simp
def simp_Chan(name): simp = moose.HHChannel2D( '/library/' + name ) simp.Ek = ECa simp.Gbar = 300.0*SOMA_A simp.Gk = 0.0 simp.Xpower = 1.0 simp.Ypower = 0.0 simp.Zpower = 1.0 simp.Xindex = 'VOLT_INDEX' # simp.Yindex = 'VOLT_INDEX' simp.Zindex = 'VOLT_C1_INDEX' simp.instant = 4 xgate = moose.element( simp.path + '/gateX' ) xgate.xminA = Vmin xgate.xmaxA = Vmax xgate.xdivsA = 0 xgate.yminA = Vmin xgate.ymaxA = Vmax xgate.ydivsA = Vdivs xgate.xminB = Vmin xgate.xmaxB = Vmax xgate.xdivsB = 0 xgate.yminB = Vmin xgate.ymaxB = Vmax xgate.ydivsB = Vdivs zgate = moose.element( simp.path + '/gateZ' ) zgate.xminA = Vmin zgate.xmaxA = Vmax zgate.xdivsA = Vdivs zgate.yminA = Camin zgate.ymaxA = Camax zgate.ydivsA = Cadivs zgate.xminB = Vmin zgate.xmaxB = Vmax zgate.xdivsB = Vdivs zgate.yminB = Camin zgate.ymaxB = Camax zgate.ydivsB = Cadivs cai = 0.05e-3 cao = 2 q10 = 5 mmin=0.2 hmin=10 a0h =0.015 zetah = 3.5 vhalfh = -75 gmh=0.6 a0m =0.04 zetam = 2 vhalfm = -28 gmm=0.1 qt=q10**((celsius-25)/10) a = 0.2*(-1.0*v*1e3+19.26)/(np.exp((-1.0*v*1e3+19.26)/10.0)-1.0) b = 0.009*np.exp(-v*1e3/22.03) minf = a/(a+b) alpmt = np.exp(0.0378*zetam*(v*1e3-vhalfm)) betmt = np.exp(0.0378*zetam*gmm*(v*1e3-vhalfm)) mtau = betmt/(qt*a0m*(1+alpmt)) mtau[mtau<mmin]=mmin tblA = np.zeros([2,xgate.ydivsA]) tblB = np.zeros([2,xgate.ydivsB]) x = Vmin for i in np.arange(2): tblA[i] = minf/mtau tblB[i] = 1/minf x = x + dV print(i, end='\r') # tblA = np.transpose(minf/mtau) # tblB = np.transpose(1/mtau) # tblA = np.reshape(np.tile(minf/mtau,xgate.ydivsA),(xgate.xdivsA,xgate.ydivsA)) # tblB = np.reshape(np.tile(1/mtau,xgate.ydivsA),(xgate.xdivsA,xgate.ydivsA)) xgate.tableA = tblA*1e3 xgate.tableB = tblB*1e3 z = 2 T = celsius+273.15 cao = 2 ezfrt = np.exp(z*v*F/R/T) x = Vmin tblA = np.zeros([zgate.xdivsA,zgate.ydivsA]) tblB = np.zeros([zgate.xdivsB,zgate.ydivsB]) for i in np.arange(zgate.ydivsA): tblA[:,i] = v*(ca[i]/cao*ezfrt-1)/(ezfrt-1)/(v-ECa) x = x + dV print(i, end='\r') tblB = tblA*0 +1 zgate.tableA = tblA zgate.tableB = tblB addmsg4 = moose.Mstring( simp.path + '/addmsg4' ) addmsg4.value = '../Ca_conc concOut . concen' addmsg2 = moose.Mstring( simp.path + '/addmsg2' ) addmsg2.value = '. IkOut ../Ca_conc current' return simp
def connect_CaConc(compartment_list, temperature=None): """ Connect the Ca pools and channels within each of the compartments in compartment_list Ca channels should have a child Mstring named 'ion' with value set in MOOSE. Ca dependent channels like KCa should have a child Mstring called 'ionDependency' with value set in MOOSE. Call this only after instantiating cell so that all channels and pools have been created. """ for compartment in compartment_list: caconc = None for child in compartment.children: if child.className == "CaConc": caconc = moose.element(child) break if caconc is not None: child = get_child_Mstring(caconc, "phi") if child is not None: caconc.B = float( child.value ) # B = phi by definition -- see neuroml 1.8.1 defn else: ## B has to be set for caconc based on thickness of Ca shell and compartment l and dia, ## OR based on the Mstring phi under CaConc path. ## I am using a translation from Neuron for mitral cell, hence this method. ## In Genesis, gmax / (surfacearea*thick) is set as value of B! caconc.B = (1 / (2 * FARADAY) / (math.pi * compartment.diameter * compartment.length * caconc.thick)) for neutralwrap in compartment.children: if neutralwrap.className == "HHChannel": channel = moose.HHChannel(child) ## If child Mstring 'ion' is present and is Ca, connect channel current to caconc for childid in channel.children: # in async13, gates which have not been created still 'exist' # i.e. show up as a child, but cannot be wrapped. try: child = moose.element(childid) if child.className == "Mstring": child = moose.Mstring(child) assert child if child.name == "ion": if child.value in ["Ca", "ca"]: moose.connect(channel, "IkOut", caconc, "current") # print 'Connected IkOut of',channel.path,'to current of',caconc.path ## temperature is used only by Nernst part here... if child.name == "nernst_str": nernst = moose.Nernst(channel.path + "/nernst") nernst_params = child.value.split(",") nernst.Cout = float(nernst_params[0]) nernst.valence = int(nernst_params[1]) nernst.Temperature = temperature moose.connect(nernst, "Eout", channel, "setEk") moose.connect(caconc, "concOut", nernst, "ci") # print 'Connected Nernst',nernst.path except TypeError: pass if neutralwrap.className == "HHChannel2D": channel = moose.HHChannel2D(child) ## If child Mstring 'ionDependency' is present, connect caconc Ca conc to channel for childid in channel.children: # in async13, gates which have not been created still 'exist' # i.e. show up as a child, but cannot be wrapped. try: child = moose.element(childid) if (child.className == "Mstring" and child.name == "ionDependency"): child = moose.Mstring(child) if child.value in ["Ca", "ca"]: moose.connect(caconc, "concOut", channel, "concen") # print 'Connected concOut of',caconc.path,'to concen of',channel.path except TypeError as e: logger_.warning(e)
def readChannelML(self, channelElement, params={}, units="SI units"): """Loads a single channel """ # I first calculate all functions assuming a consistent system of units. # While filling in the A and B tables, I just convert to SI. Also # convert gmax and Erev. if 'Physiological Units' in units: # see pg 219 (sec 13.2) of Book of Genesis Vfactor = 1e-3 # V from mV Tfactor = 1e-3 # s from ms Gfactor = 1e1 # S/m^2 from mS/cm^2 concfactor = 1e6 # Mol = mol/m^-3 from mol/cm^-3 elif 'SI Units' in units: Vfactor = 1.0 Tfactor = 1.0 Gfactor = 1.0 concfactor = 1.0 else: debug.printDebug("ERR", "wrong units %s. Existing... " % units, frame=inspect.currentframe()) raise UserWarning, "Unknown units" # creates /library in MOOSE tree; elif present, wraps channel_name = channelElement.attrib['name'] if utils.neuroml_debug: msg = "Loading channel {} into {} ".format(channel_name, self.libraryPath) debug.printDebug("INFO", msg) IVrelation = channelElement.find('./{' + self.cml + '}current_voltage_relation') concdep = IVrelation.find('./{' + self.cml + '}conc_dependence') cPath = os.path.join(self.libraryPath, channel_name) if concdep is None: channel = moose.HHChannel(cPath) else: channel = moose.HHChannel2D(cPath) if IVrelation.attrib['cond_law'] == "ohmic": channel.Gbar = float(IVrelation.attrib['default_gmax']) * Gfactor channel.Ek = float(IVrelation.attrib['default_erev']) * Vfactor channelIon = moose.Mstring(channel.path + '/ion') channelIon.value = IVrelation.attrib['ion'] if concdep is not None: channelIonDependency = moose.Mstring(channel.path + '/ionDependency') channelIonDependency.value = concdep.attrib['ion'] nernstnote = IVrelation.find('./{' + utils.meta_ns + '}notes') if nernstnote is not None: # the text in nernstnote is "Nernst,Cout=<float>,z=<int>" nernst_params = string.split(nernstnote.text, ',') if nernst_params[0] == 'Nernst': nernstMstring = moose.Mstring(channel.path + '/nernst_str') nernstMstring.value = str( float(string.split(nernst_params[1], '=')[1]) * concfactor) + ',' + str( int(string.split(nernst_params[2], '=')[1])) gates = IVrelation.findall('./{' + self.cml + '}gate') if len(gates) > 3: msg = "Sorry! Maximum x, y, and z (three) gates are possible in\ MOOSE/Genesis" debug.printDebug("ERR", msg, frame=inspect.currentframe()) raise UserWarning, "Bad value or parameter" # These are the names that MOOSE uses to create gates. gate_full_name = ['gateX', 'gateY', 'gateZ'] # if impl_prefs tag is present change VMIN, VMAX and NDIVS impl_prefs = channelElement.find('./{' + self.cml + '}impl_prefs') if impl_prefs is not None: table_settings = impl_prefs.find('./{' + self.cml + '}table_settings') # some problem here... disable VMIN_here = float(table_settings.attrib['min_v']) VMAX_here = float(table_settings.attrib['max_v']) NDIVS_here = int(table_settings.attrib['table_divisions']) dv_here = (VMAX_here - VMIN_here) / NDIVS_here else: # default VMIN, VMAX and dv are in SI convert them to current # calculation units used by channel definition while loading into # tables, convert them back to SI VMIN_here = utils.VMIN / Vfactor VMAX_here = utils.VMAX / Vfactor NDIVS_here = utils.NDIVS dv_here = utils.dv / Vfactor offset = IVrelation.find('./{' + self.cml + '}offset') if offset is None: vNegOffset = 0.0 else: vNegOffset = float(offset.attrib['value']) self.parameters = [] for parameter in channelElement.findall('.//{' + self.cml + '}parameter'): self.parameters.append( (parameter.attrib['name'], float(parameter.attrib['value']))) for num, gate in enumerate(gates): # if no q10settings tag, the q10factor remains 1.0 if present but no # gate attribute, then set q10factor if there is a gate attribute, # then set it only if gate attrib matches gate name self.q10factor = 1.0 self.gate_name = gate.attrib['name'] q10sets = IVrelation.findall('./{' + self.cml + '}q10_settings') for q10settings in q10sets: # self.temperature from neuro.utils if 'gate' in list(q10settings.attrib.keys()): if q10settings.attrib['gate'] == self.gate_name: self.setQ10(q10settings) break else: self.setQ10(q10settings) # HHChannel2D crashing on setting Xpower! temperamental! If you # print something before, it gives cannot creategate from copied # channel, else crashes Setting power first. This is necessary # because it also initializes the gate's internal data structures as # a side effect. Alternatively, gates can be initialized explicitly # by calling HHChannel.createGate(). gate_power = float(gate.get('instances')) if num == 0: channel.Xpower = gate_power if concdep is not None: channel.Xindex = "VOLT_C1_INDEX" elif num == 1: channel.Ypower = gate_power if concdep is not None: channel.Yindex = "VOLT_C1_INDEX" elif num == 2: channel.Zpower = gate_power if concdep is not None: channel.Zindex = "VOLT_C1_INDEX" ## Getting handle to gate using the gate's path. gate_path = os.path.join(channel.path, gate_full_name[num]) if concdep is None: moosegate = moose.HHGate(gate_path) # set SI values inside MOOSE moosegate.min = VMIN_here * Vfactor moosegate.max = VMAX_here * Vfactor moosegate.divs = NDIVS_here ## V.IMP to get smooth curves, else even with 3000 divisions ## there are sudden transitions. moosegate.useInterpolation = True else: moosegate = moose.HHGate2D(gate_path) # If alpha and beta functions exist, make them here for transition in gate.findall('./{' + self.cml + '}transition'): # make python functions with names of transitions... fn_name = transition.attrib['name'] # I assume that transitions if present are called alpha and beta # for forwand backward transitions... if fn_name in ['alpha', 'beta']: self.make_cml_function(transition, fn_name, concdep) else: debug.printDebug( "ERROR", "Unsupported transition {0}".format(fn_name)) sys.exit() time_course = gate.find('./{' + self.cml + '}time_course') # tau is divided by self.q10factor in make_function() thus, it gets # divided irrespective of <time_course> tag present or not. if time_course is not None: self.make_cml_function(time_course, 'tau', concdep) steady_state = gate.find('./{' + self.cml + '}steady_state') if steady_state is not None: self.make_cml_function(steady_state, 'inf', concdep) if concdep is None: ca_name = '' # no Ca dependence else: # Ca dependence ca_name = ',' + concdep.attrib['variable_name'] # Create tau() and inf() if not present, from alpha() and beta() for fn_element, fn_name, fn_expr in [ (time_course, 'tau', "1/(alpha+beta)"), (steady_state, 'inf', "alpha/(alpha+beta)") ]: # put in args for alpha and beta, could be v and Ca dep. expr_string = self.replace(fn_expr, 'alpha', 'self.alpha(v' + ca_name + ')') expr_string = self.replace(expr_string, 'beta', 'self.beta(v' + ca_name + ')') # if time_course/steady_state are not present, then alpha annd # beta transition elements should be present, and fns created. if fn_element is None: self.make_function(fn_name, 'generic', expr_string=expr_string, concdep=concdep) # non Ca dependent channel if concdep is None: # while calculating, use the units used in xml defn, while # filling in table, I convert to SI units. v0 = VMIN_here - vNegOffset n_entries = NDIVS_here + 1 tableA = [0.0] * n_entries tableB = [0.0] * n_entries for i in range(n_entries): v = v0 + (i * dv_here) inf = self.inf(v) tau = self.tau(v) # convert to SI before writing to table # qfactor is already in inf and tau tableA[i] = (inf / tau) / Tfactor tableB[i] = (1.0 / tau) / Tfactor moosegate.tableA = tableA moosegate.tableB = tableB ## Ca dependent channel else: # UNITS: while calculating, use the units used in xml defn, # while filling in table, I convert to SI units. Note here Ca # units do not enter, but units of CaMIN, CaMAX and ca_conc in # fn expr should match. v = VMIN_here - vNegOffset CaMIN = float(concdep.attrib['min_conc']) CaMAX = float(concdep.attrib['max_conc']) CaNDIVS = 100 dCa = (CaMAX - CaMIN) / CaNDIVS # CAREFUL!: tableA = [[0.0]*(CaNDIVS+1)]*(NDIVS_here+1) will not # work! * does a shallow copy, same list will get repeated 200 # times! Thus setting tableA[35][1] = 5.0 will set all rows, # 1st col to 5.0!!!! tableA = [[0.0] * (CaNDIVS + 1) for i in range(NDIVS_here + 1)] tableB = [[0.0] * (CaNDIVS + 1) for i in range(NDIVS_here + 1)] for i in range(NDIVS_here + 1): Ca = CaMIN for j in range(CaNDIVS + 1): inf = self.inf(v, Ca) tau = self.tau(v, Ca) # convert to SI (Tfactor) before writing to table # qfactor is already in inf and tau tableA[i][j] = (inf / tau) / Tfactor tableB[i][j] = (1.0 / tau) / Tfactor Ca += dCa v += dv_here # Presently HHGate2D doesn't allow the setting of tables as 2D # vectors directly #moosegate.tableA = tableA #moosegate.tableB = tableB # Instead, I wrap the interpol2D objects inside HHGate2D and set # the tables moosegate_tableA = moose.Interpol2D(moosegate.path + '/tableA') # set SI values inside MOOSE moosegate_tableA.xmin = VMIN_here * Vfactor moosegate_tableA.xmax = VMAX_here * Vfactor moosegate_tableA.xdivs = NDIVS_here #moosegate_tableA.dx = dv_here*Vfactor moosegate_tableA.ymin = CaMIN * concfactor moosegate_tableA.ymax = CaMAX * concfactor moosegate_tableA.ydivs = CaNDIVS #moosegate_tableA.dy = dCa*concfactor moosegate_tableA.tableVector2D = tableA moosegate_tableB = moose.Interpol2D(moosegate.path + '/tableB') ## set SI values inside MOOSE moosegate_tableB.xmin = VMIN_here * Vfactor moosegate_tableB.xmax = VMAX_here * Vfactor moosegate_tableB.xdivs = NDIVS_here #moosegate_tableB.dx = dv_here*Vfactor moosegate_tableB.ymin = CaMIN * concfactor moosegate_tableB.ymax = CaMAX * concfactor moosegate_tableB.ydivs = CaNDIVS #moosegate_tableB.dy = dCa*concfactor moosegate_tableB.tableVector2D = tableB
def simp_Chan(name): simp = moose.HHChannel2D('/library/' + name) simp.Ek = ECa simp.Gbar = 300.0 * SOMA_A simp.Gk = 0.0 simp.Xpower = 1.0 simp.Ypower = 0.0 simp.Zpower = 1.0 simp.Xindex = 'VOLT_INDEX' # simp.Yindex = 'VOLT_INDEX' simp.Zindex = 'VOLT_C1_INDEX' simp.instant = 4 xgate = moose.element(simp.path + '/gateX') xgate.xminA = Vmin xgate.xmaxA = Vmax xgate.xdivsA = Vdivs xgate.yminA = Vmin xgate.ymaxA = Vmax xgate.ydivsA = Vdivs xgate.xminB = Vmin xgate.xmaxB = Vmax xgate.xdivsB = Vdivs xgate.yminB = Vmin xgate.ymaxB = Vmax xgate.ydivsB = Vdivs zgate = moose.element(simp.path + '/gateZ') zgate.xminA = Vmin zgate.xmaxA = Vmax zgate.xdivsA = Vdivs zgate.yminA = Camin zgate.ymaxA = Camax zgate.ydivsA = Cadivs zgate.xminB = Vmin zgate.xmaxB = Vmax zgate.xdivsB = Vdivs zgate.yminB = Camin zgate.ymaxB = Camax zgate.ydivsB = Cadivs cao = 2 q10 = 5 mmin = 0.2 hmin = 10 a0h = 0.015 zetah = 3.5 vhalfh = -75 gmh = 0.6 a0m = 0.04 zetam = 2 vhalfm = -28 gmm = 0.1 qt = q10**((celsius - 25) / 10) a = 0.2 * (-1.0 * v * 1e3 + 19.26) / (np.exp( (-1.0 * v * 1e3 + 19.26) / 10.0) - 1.0) b = 0.009 * np.exp(-v * 1e3 / 22.03) minf = a / (a + b) alpmt = np.exp(0.0378 * zetam * (v * 1e3 - vhalfm)) betmt = np.exp(0.0378 * zetam * gmm * (v * 1e3 - vhalfm)) mtau = betmt / (qt * a0m * (1 + alpmt)) mtau[mtau < mmin] = mmin # tblA = np.zeros([1,xgate.ydivsA]) # tblB = np.zeros([1,xgate.ydivsB]) # tblA[0] = minf/mtau*1e3 # tblB[0] = 1/mtau*1e3 tblA = np.zeros([xgate.xdivsA, 1]) tblB = np.zeros([xgate.xdivsB, 1]) for i in np.arange(1): tblA[:, i] = minf / mtau * 1e3 tblB[:, i] = 1 / mtau * 1e3 print(i, end='\r') # tblB = tblA*0 +1 xgate.tableA = tblA xgate.tableB = tblB # for i in np.arange(1,xgate.ydivsB): # tblA[i] = minf/mtau*0+1 # tblB[i] = 1/mtau*0+1 # print(i, end='\r') # tblA[:,0] = minf/mtau*1e3 # tblB[:,0] = 1/mtau*1e3 # print('X setup') # tblA = np.transpose(minf/mtau) # tblB = np.transpose(1/mtau) # tblA = np.reshape(np.tile(minf/mtau,xgate.ydivsA),(xgate.xdivsA,xgate.ydivsA)) # tblB = np.reshape(np.tile(1/mtau,xgate.ydivsA),(xgate.xdivsA,xgate.ydivsA)) print('xgate.tableA') print(xgate.tableA) print(np.shape(xgate.tableA)) print('xgate.tableB') print(xgate.tableB) print('###########################################') z = 2 T = celsius + 273.15 cao = 2 ezfrt = np.exp(z * v * F / R / T) # ezfrt = np.exp(z*v*1e3*293.15/25/T) #Used in NEURON. gives very slightly different values tblA = np.zeros([zgate.xdivsA, zgate.ydivsA]) tblB = np.zeros([zgate.xdivsB, zgate.ydivsB]) for i in np.arange(zgate.ydivsA): tblA[:, i] = v * (ca[i] / cao * ezfrt - 1) / (ezfrt - 1) / (v - ECa) print(i, end='\r') tblB = tblA * 0 + 1 zgate.tableA = tblA zgate.tableB = tblB print('zgate.tableA') print(zgate.tableA) print(np.shape(zgate.tableA)) print('zgate.tableB') print(zgate.tableB) addmsg4 = moose.Mstring(simp.path + '/addmsg4') addmsg4.value = '../Ca_conc concOut . concen' addmsg2 = moose.Mstring(simp.path + '/addmsg2') addmsg2.value = '. IkOut ../Ca_conc current' return simp