def create_squid(): """Create a single compartment squid model.""" parent = moose.Neutral('/n') compt = moose.SymCompartment('/n/compt') Em = EREST_ACT + 10.613e-3 compt.Em = Em compt.initVm = EREST_ACT compt.Cm = 7.85e-9 * 0.5 compt.Rm = 4.2e5 * 5.0 compt.Ra = 7639.44e3 nachan = moose.HHChannel('/n/compt/Na') nachan.Xpower = 3 xGate = moose.HHGate(nachan.path + '/gateX') xGate.setupAlpha(Na_m_params + [VDIVS, VMIN, VMAX]) #This is important: one can run without it but the output will diverge. xGate.useInterpolation = 1 nachan.Ypower = 1 yGate = moose.HHGate(nachan.path + '/gateY') yGate.setupAlpha(Na_h_params + [VDIVS, VMIN, VMAX]) yGate.useInterpolation = 1 nachan.Gbar = 0.942e-3 nachan.Ek = 115e-3 + EREST_ACT moose.connect(nachan, 'channel', compt, 'channel', 'OneToOne') kchan = moose.HHChannel('/n/compt/K') kchan.Xpower = 4.0 xGate = moose.HHGate(kchan.path + '/gateX') xGate.setupAlpha(K_n_params + [VDIVS, VMIN, VMAX]) xGate.useInterpolation = 1 kchan.Gbar = 0.2836e-3 kchan.Ek = -12e-3 + EREST_ACT moose.connect(kchan, 'channel', compt, 'channel', 'OneToOne') return compt
def createSquid(): """Create a single compartment squid model.""" parent = moose.Neutral('/n') elec = moose.Neutral('/n/elec') compt = moose.SymCompartment('/n/elec/compt') Em = EREST_ACT + 10.613e-3 compt.Em = Em compt.initVm = EREST_ACT compt.Cm = 7.85e-9 * 0.5 compt.Rm = 4.2e5 * 5.0 compt.Ra = 7639.44e3 compt.length = 100e-6 compt.diameter = 4e-6 nachan = moose.HHChannel('/n/elec/compt/Na') nachan.Xpower = 3 xGate = moose.HHGate(nachan.path + '/gateX') xGate.setupAlpha(Na_m_params + [VDIVS, VMIN, VMAX]) xGate.useInterpolation = 1 nachan.Ypower = 1 yGate = moose.HHGate(nachan.path + '/gateY') yGate.setupAlpha(Na_h_params + [VDIVS, VMIN, VMAX]) yGate.useInterpolation = 1 nachan.Gbar = 0.942e-3 nachan.Ek = 115e-3 + EREST_ACT moose.connect(nachan, 'channel', compt, 'channel', 'OneToOne') kchan = moose.HHChannel('/n/elec/compt/K') kchan.Xpower = 4.0 xGate = moose.HHGate(kchan.path + '/gateX') xGate.setupAlpha(K_n_params + [VDIVS, VMIN, VMAX]) xGate.useInterpolation = 1 kchan.Gbar = 0.2836e-3 kchan.Ek = -12e-3 + EREST_ACT moose.connect(kchan, 'channel', compt, 'channel', 'OneToOne') return compt
def makeChannelPrototypes(): """Create channel prototypes for readcell.""" library = moose.Neutral('/library') moose.setCwe('/library') compt = moose.SymCompartment('/library/symcompartment') Em = EREST_ACT + 10.613e-3 compt.Em = Em compt.initVm = EREST_ACT compt.Cm = 7.85e-9 * 0.5 compt.Rm = 4.2e5 * 5.0 compt.Ra = 7639.44e3 nachan = moose.HHChannel('/library/Na') nachan.Xpower = 3 xGate = moose.HHGate(nachan.path + '/gateX') xGate.setupAlpha(Na_m_params + [VDIVS, VMIN, VMAX]) xGate.useInterpolation = 1 nachan.Ypower = 1 yGate = moose.HHGate(nachan.path + '/gateY') yGate.setupAlpha(Na_h_params + [VDIVS, VMIN, VMAX]) yGate.useInterpolation = 1 nachan.Gbar = 0.942e-3 nachan.Ek = 115e-3 + EREST_ACT kchan = moose.HHChannel('/library/K') kchan.Xpower = 4.0 xGate = moose.HHGate(kchan.path + '/gateX') xGate.setupAlpha(K_n_params + [VDIVS, VMIN, VMAX]) xGate.useInterpolation = 1 kchan.Gbar = 0.2836e-3 kchan.Ek = -12e-3 + EREST_ACT
def setupAlpha(self, gate, params, vdivs, vmin, vmax): """Setup alpha and beta parameters of specified gate. gate -- 'X'/'Y'/'Z' string initial of the gate. params -- dict of parameters to compute alpha and beta, the rate constants for gates. vdivs -- number of divisions in the interpolation tables for alpha and beta parameters. vmin -- minimum voltage value for the alpha/beta lookup tables. vmax -- maximum voltage value for the alpha/beta lookup tables. """ if gate == "X" and self.chan.Xpower > 0: gate = moose.HHGate(self.path + "/gateX") elif gate == "Y" and self.chan.Ypower > 0: gate = moose.HHGate(self.path + "/gateY") else: return False gate.setupAlpha([ params["A_A"], params["A_B"], params["A_C"], params["A_D"], params["A_F"], params["B_A"], params["B_B"], params["B_C"], params["B_D"], params["B_F"], vdivs, vmin, vmax, ]) return True
def beta_h(self): if self.Ypower == 0: return numpy.array([]) return numpy.array(moose.HHGate('%s/gateY' % (self.path)).tableB) - numpy.array( moose.HHGate('%s/gateY' % (self.path)).tableA)
def create_channel_proto(channelSettings, vDivs=3000, vMin=-30e-3 + EREST_ACT, vMax=120e-3 + EREST_ACT, caDivs=10000, caMin=0, caMax=1): if (not (moose.exists("/library"))): moose.Neutral('/library') channel = moose.HHChannel('/library/' + channelSettings.name) channel.tick = -1 if (channelSettings.xPower > 0): channel.Xpower = channelSettings.xPower xGate = moose.HHGate(channel.path + "/gateX") xGate.setupAlpha(channelSettings.xParam + (vDivs, vMin, vMax)) if (channelSettings.yPower > 0): channel.Ypower = channelSettings.yPower yGate = moose.HHGate(channel.path + "/gateY") yGate.setupAlpha(channelSettings.yParam + (vDivs, vMin, vMax)) if (channelSettings.zPower > 0): channel.Zpower = channelSettings.zPower zGate = moose.HHGate(channel.path + "/gateZ") zGate.min = caMin zGate.max = caMax caTerm = (np.linspace(caMin, caMax, caDivs) / channelSettings.zParam.Kd)**channelSettings.zParam.power inf_z = caTerm / ( 1 + caTerm ) # open probability at steady state for a given Ca concentration tau_z = channelSettings.zParam.tau * np.ones( caDivs) # constant tau for any Ca concentration zGate.tableA = inf_z / tau_z #alpha zGate.tableB = 1 / tau_z #alpha + beta? channel.useConcentration = True return channel
def chan_proto(chanpath, params): import param_chan chan = moose.HHChannel(chanpath) chan.Xpower = params.channel.Xpow if params.channel.Xpow > 0: xGate = moose.HHGate(chan.path + '/gateX') xGate.setupAlpha(params.X + (param_chan.VDIVS, param_chan.VMIN, param_chan.VMAX)) xGate = fix_singularities(params.X, xGate) chan.Ypower = params.channel.Ypow if params.channel.Ypow > 0: yGate = moose.HHGate(chan.path + '/gateY') yGate.setupAlpha(params.Y + (param_chan.VDIVS, param_chan.VMIN, param_chan.VMAX)) yGate = fix_singularities(params.Y, yGate) if params.channel.Zpow > 0: chan.Zpower = params.channel.Zpow zgate = moose.HHGate(chan.path + '/gateZ') ca_array = np.linspace(param_chan.CAMIN, param_chan.CAMAX, param_chan.CADIVS) zgate.min = param_chan.CAMIN zgate.max = param_chan.CAMAX caterm = (ca_array / params.Z.Kd)**params.Z.power inf_z = caterm / (1 + caterm) tau_z = params.Z.tau * np.ones(len(ca_array)) zgate.tableA = inf_z / tau_z zgate.tableB = 1 / tau_z chan.useConcentration = True chan.Ek = params.channel.Erev return chan
def create_squid(): """Create a single compartment squid model.""" parent = moose.Neutral('/n') compt = moose.Compartment('/n/compt') Em = EREST_ACT + 10.613e-3 compt.Em = Em compt.initVm = EREST_ACT compt.Cm = 7.85e-9 compt.Rm = 4.2e5 compt.Ra = 7639.44e3 nachan = moose.HHChannel('/n/compt/Na') nachan.Xpower = 3 xGate = moose.HHGate(nachan.path + '/gateX') xGate.setupAlpha(Na_m_params + [VDIVS, VMIN, VMAX]) nachan.Ypower = 1 yGate = moose.HHGate(nachan.path + '/gateY') yGate.setupAlpha(Na_h_params + [VDIVS, VMIN, VMAX]) nachan.Gbar = 0.942e-3 nachan.Ek = 115e-3 + EREST_ACT moose.connect(nachan, 'channel', compt, 'channel', 'OneToOne') kchan = moose.HHChannel('/n/compt/K') kchan.Xpower = 4.0 xGate = moose.HHGate(kchan.path + '/gateX') xGate.setupAlpha(K_n_params + [VDIVS, VMIN, VMAX]) kchan.Gbar = 0.2836e-3 kchan.Ek = -12e-3 + EREST_ACT moose.connect(kchan, 'channel', compt, 'channel', 'OneToOne') return compt
def createChanProto(libraryName, channelParams, rateParams): # Create a library to store the channel prototypes if not moose.exists(libraryName): lib = moose.Neutral(libraryName) else: lib = moose.element(libraryName) # Create the channel and set the powers and reversal potential channel = moose.HHChannel(lib.path + '/' + channelParams.name) channel.Ek = channelParams.Erev channel.Xpower = channelParams.Xpow channel.Ypower = channelParams.Ypow # Define the activation gating kinetics if they exist if channel.Xpower > 0: xGate = moose.HHGate(channel.path + '/' + 'gateX') xGate.setupAlpha(channelParams.Xparam + rateParams) # Define the inactivation gating kinetics if they exist if channel.Ypower > 0: yGate = moose.HHGate(channel.path + '/' + 'gateY') yGate.setupAlpha(channelParams.Yparam + rateParams) # Set the tick for the channel so that it is set appropriately when it # is copied to a channel from the library channel.tick = -1 return channel
def __new__(cls, name, bases, cdict): global prototypes # classes that set absract=True will be # abstract classes. Others will have the prototype insatntiated. if 'abstract' in cdict and cdict['abstract'] == True: return type.__new__(cls, name, bases, cdict) proto = moose.HHChannel('%s/%s' % (config.library.path, name)) xpower = get_class_field(name, cdict, bases, 'Xpower', default=0.0) if xpower > 0: proto.Xpower = xpower gate = moose.HHGate('%s/gateX' % (proto.path)) setup_gate_tables(gate, cdict, bases) cdict['xGate'] = gate ypower = get_class_field(name, cdict, bases, 'Ypower', default=0.0) if ypower > 0: proto.Ypower = ypower gate = moose.HHGate('%s/gateY' % (proto.path)) setup_gate_tables(gate, cdict, bases) cdict['yGate'] = gate zpower = get_class_field(name, cdict, bases, 'Zpower', default=0.0) if zpower > 0: proto.Zpower = zpower gate = moose.HHGate('%s/gateZ' % (proto.path)) setup_gate_tables(gate, cdict, bases) cdict['zGate'] = gate ca_msg_field = moose.Mstring('%s/addmsg1' % (proto.path)) ca_msg_field.value = '../CaPool concOut . concen' proto.instant = get_class_field(name, cdict, bases, 'instant', default=0) proto.useConcentration = True proto.Ek = get_class_field(name, cdict, bases, 'Ek', default=0.0) X = get_class_field(name, cdict, bases, 'X') if X is not None: proto.X = X Y = get_class_field(name, cdict, bases, 'Y') if Y is not None: proto.Y = Y Z = get_class_field(name, cdict, bases, 'Z') if Z is not None: proto.Z = Z mstring_field = get_class_field(name, cdict, bases, 'mstring') if mstring_field is not None: # print 'mstring_field:', mstring_field mstring = moose.Mstring('%s/%s' % (proto.path, mstring_field[0])) mstring.value = mstring_field[1] if 'annotation' in cdict: info = moose.Annotator('%s/info' % (proto.path)) info.notes = '\n'.join('%s: %s' % kv for kv in list(cdict['annotation'].items())) # print proto.path, info.notes cdict['prototype'] = proto prototypes[name] = proto config.logger.info('Created prototype: %s of class %s' % (proto.path, name)) return type.__new__(cls, name, bases, cdict)
def create_na_chan(path): na = moose.HHChannel('%s/na' % (path)) na.Xpower = 3 xGate = moose.HHGate(na.path + '/gateX') xGate.setupAlpha(Na_m_params + [VDIVS, VMIN, VMAX]) na.Ypower = 1 yGate = moose.HHGate(na.path + '/gateY') yGate.setupAlpha(Na_h_params + [VDIVS, VMIN, VMAX]) na.Ek = 115e-3 + EREST_ACT return na
def create_na_proto(): lib = moose.Neutral('/library') na = moose.HHChannel('/library/na') na.Xpower = 3 xGate = moose.HHGate(na.path + '/gateX') xGate.setupAlpha(Na_m_params + [VDIVS, VMIN, VMAX]) na.Ypower = 1 yGate = moose.HHGate(na.path + '/gateY') yGate.setupAlpha(Na_h_params + [VDIVS, VMIN, VMAX]) return na
def create_channel(channelSettings, vDivs = 3000, vMin = -30e-3 + EREST_ACT, vMax = 120e-3 + EREST_ACT): if(not(moose.exists("/library"))): moose.Neutral('/library') channel = moose.HHChannel('/library/' + channelSettings.name) channel.tick = -1 if(channelSettings.xPower > 0): channel.Xpower = channelSettings.xPower xGate = moose.HHGate(channel.path + "/gateX") xGate.setupAlpha(channelSettings.xParam + (vDivs, vMin, vMax)) if(channelSettings.yPower > 0): channel.Ypower = channelSettings.yPower yGate = moose.HHGate(channel.path + "/gateY") yGate.setupAlpha(channelSettings.yParam + (vDivs, vMin, vMax)) return channel
def __init__(self, *args): """Setup the Na channel with defaults""" moose.HHChannel.__init__(self, *args) self.Ek = VNa self.Gbar = GNa self.addField('ion') self.setField('ion', 'Na') self.Xpower = 3 # This will create HHGate instance xGate inside the Na channel self.Ypower = 1 # This will create HHGate instance yGate inside the Na channel # These gates get created only after Xpower or Ypower are set to nonzero values # So we have to explicitly insert these fields in the class self.xGate = moose.HHGate(self.path + "/xGate") self.yGate = moose.HHGate(self.path + "/yGate") tabchan_file = open("channels/tabchannels.dat") nagran_NDIVS = 1000 # ensure that there are 1001 lines in these above data files self.xGate.A.xmin = VMIN self.xGate.A.xmax = VMAX self.xGate.A.xdivs = nagran_NDIVS self.xGate.B.xmin = VMIN self.xGate.B.xmax = VMAX self.xGate.B.xdivs = nagran_NDIVS self.yGate.A.xmin = VMIN self.yGate.A.xmax = VMAX self.yGate.A.xdivs = nagran_NDIVS self.yGate.B.xmin = VMIN self.yGate.B.xmax = VMAX self.yGate.B.xdivs = nagran_NDIVS v = VMIN for i in range(nagran_NDIVS + 1): ## The files are from Davison's model, physiological units ms^-1, so convert (minf_s, mtau_ms_s, hinf_s, htau_ms_s) = tabchan_file.readline( ).split( )[9: 13] # split each line in the file on whitespace and take the 10th to 13th columns (see tabchannels.hoc for parsing). minf = float(minf_s) mtau = float(mtau_ms_s) * 1.0e-3 hinf = float(hinf_s) htau = float(htau_ms_s) * 1.0e-3 self.xGate.A[i] = minf / mtau self.xGate.B[ i] = 1.0 / mtau ### Python version below 3.0 will treat 1/x as integer division! Use 1.0/x !!!! self.yGate.A[i] = hinf / htau self.yGate.B[i] = 1.0 / htau v = v + dv tabchan_file.close()
def create_k_chan(path): k = moose.HHChannel('%s/k' % (path)) k.Xpower = 4.0 xGate = moose.HHGate(k.path + '/gateX') xGate.setupAlpha(K_n_params + [VDIVS, VMIN, VMAX]) k.Ek = -12e-3 + EREST_ACT return k
def create_k_proto(): lib = moose.Neutral('/library') k = moose.HHChannel('/library/k') k.Xpower = 4.0 xGate = moose.HHGate(k.path + '/gateX') xGate.setupAlpha(K_n_params + [VDIVS, VMIN, VMAX]) return k
def createChanProto(libraryName, channelParams, rateParams, CaParams=None): # Create a library to store the channel prototypes if not moose.exists(libraryName): lib = moose.Neutral(libraryName) else: lib = moose.element(libraryName) # Create the channel and set the powers and reversal potential channel = moose.HHChannel(lib.path + '/' + channelParams.name) channel.Ek = channelParams.Erev channel.Xpower = channelParams.Xpow channel.Ypower = channelParams.Ypow channel.Zpower = channelParams.Zpow # Define the activation gating kinetics if they exist if channel.Xpower > 0: xGate = moose.HHGate(channel.path + '/' + 'gateX') xGate.setupAlpha(channelParams.Xparam + rateParams) # Define the inactivation gating kinetics if they exist if channel.Ypower > 0: yGate = moose.HHGate(channel.path + '/' + 'gateY') yGate.setupAlpha(channelParams.Yparam + rateParams) if channel.Zpower > 0: channel.Zpower = channelParams.Zpow ca_array = np.linspace(CaParams[0], CaParams[1], CaParams[2]) zGate = moose.HHGate(channel.path + '/' + 'gateZ') zGate.min = CaParams[0] zGate.max = CaParams[1] # custom equation for the Ca dynamics caterm = (ca_array / channelParams.Zparam.Kd) caterm = caterm**channelParams.Zparam.power inf_z = caterm / (1 + caterm) tau_z = channelParams.Zparam.tau * np.ones(len(ca_array)) # How to fill the A and B tables with custom gating zGate.tableA = inf_z / tau_z #tableA is equivalent to alpha zGate.tableB = 1 / tau_z # tableB is equivalent to alpha+beta # Set this for z Gate channel to use concentration channel.useConcentration = True # Set the tick for the channel so that it is set appropriately when it # is copied to a channel from the library channel.tick = -1 return channel
def chan_proto(model, chanpath, params): log.info("{}: {}", chanpath, params) chan = moose.HHChannel(chanpath) chan.Xpower = params.channel.Xpow if params.channel.Xpow > 0: xGate = moose.HHGate(chan.path + '/gateX') make_gate(params.X,model,xGate) chan.Ypower = params.channel.Ypow if params.channel.Ypow > 0: yGate = moose.HHGate(chan.path + '/gateY') make_gate(params.Y,model,yGate) if params.channel.Zpow > 0: chan.Zpower = params.channel.Zpow zGate = moose.HHGate(chan.path + '/gateZ') if params.Z.__class__==ZChannelParams: # ca_array = np.linspace(model.CAMIN, model.CAMAX, model.CADIVS) zGate.min = model.CAMIN zGate.max = model.CAMAX caterm = (ca_array/params.Z.Kd) ** params.Z.power inf_z = caterm / (1 + caterm) if params.Z.taumax>0: tauterm=(ca_array/params.Z.cahalf)**params.Z.tau_power taumax_z=(params.Z.taumax-params.Z.tau)/(1+tauterm) taumin_z= params.Z.tau * np.ones(len(ca_array)) tau_z = taumin_z+taumax_z else: tau_z = params.Z.tau * np.ones(len(ca_array)) # zGate.tableA = inf_z / tau_z zGate.tableB = 1 / tau_z chan.useConcentration = True else: chan.useConcentration = False make_gate(params.Z,model,zGate) chan.Ek = params.channel.Erev chan.tick=-1 return chan
def setupAlpha(self, gate, params, vdivs, vmin, vmax): """Setup alpha and beta parameters of specified gate. gate -- 'X'/'Y'/'Z' string initial of the gate. params -- dict of parameters to compute alpha and beta, the rate constants for gates. vdivs -- number of divisions in the interpolation tables for alpha and beta parameters. vmin -- minimum voltage value for the alpha/beta lookup tables. vmax -- maximum voltage value for the alpha/beta lookup tables. """ print "~~~" print "Setting up alpha in moose" print "self.path is:" print self.path if gate == 'X' and self.Xpower > 0: print 'gate path:' print self.path + '/gateX' gate = moose.HHGate(self.path + '/gateX') elif gate == 'Y' and self.Ypower > 0: gate = moose.HHGate(self.path + '/gateY') else: print "GATE SETUP ALPHA FAILED" return False gate.setupAlpha([params['A_A'], params['A_B'], params['A_C'], params['A_D'], params['A_F'], params['B_A'], params['B_B'], params['B_C'], params['B_D'], params['B_F'], vdivs, vmin, vmax]) return True
def create_conc_dependent_z_gate(chan, params, cadivs, camin, camax): zgate = moose.HHGate(chan.path + '/gateZ') zgate.min, zgate.max = camin, camax ca_conc_points = np.linspace(camin, camax, cadivs) caterm = (ca_conc_points/params.kd) caterm = caterm ** params.power z_inf = caterm/(1+caterm) z_tau = params.tau*np.ones(len(ca_conc_points)) zgate.tableA = z_inf / z_tau zgate.tableB = 1 / z_tau chan.useConcentration = True return chan
def create_conc_dependent_z_gate(chan, params, cadivs, camin, camax): zgate = moose.HHGate(chan.path + '/gateZ') zgate.min, zgate.max = camin, camax ca_conc_points = np.linspace(camin, camax, cadivs) # z_inf = 1/(ca_conc_points**2 + params.kd**2) # As per paper. z_inf = ca_conc_points**2 / (ca_conc_points**2 + params.kd**2 ) # correction after dan email. z_tau = params.tau * np.ones(len(ca_conc_points)) zgate.tableA = z_inf / z_tau zgate.tableB = 1 / z_tau chan.useConcentration = True return chan
def create_k_proto(): """Create and return a K+ channel prototype '/library/k'. The K+ channel conductance has the equation:: g = Gbar * n^4 """ lib = moose.Neutral('/library') k = moose.HHChannel('/library/k') k.tick = -1 k.Xpower = 4.0 xGate = moose.HHGate(k.path + '/gateX') xGate.setupAlpha(K_n_params + [VDIVS, VMIN, VMAX]) return k
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
sys.path.append('..') from mooseConstants import * from load_channels import * from pylab import * if __name__ == "__main__": load_channels() idx = test_mechanism_index for varidx in range( len(mechanism_vars[idx]) / 2 ): # loop over each inf and tau i.e. two elements of mechanism_vars[idx] at a time var = ['x', 'y', 'z'][varidx] gate = moose.HHGate('/library/' + mechanism_names[idx] + '/' + var + 'Gate') VMIN = gate.A.xmin VMAX = gate.A.xmax NDIVS = gate.A.xdivs # will use same VMIN, VMAX and NDIVS for A and B tables. dv = (VMAX - VMIN) / NDIVS vrange = [VMIN + i * dv for i in range(NDIVS + 1)] figure() plot(vrange, [gate.A[i] / gate.B[i] for i in range(NDIVS + 1)], 'b-,') # Assume A and B have corresponding number of entries title('state variable ' + mechanism_vars[idx][2 * varidx] + ' of ' + mechanism_names[idx] + ' vs Voltage (V)') figure() plot(vrange, [1.0 / gate.B[i] for i in range(NDIVS + 1)], 'b-,') title('state variable ' + mechanism_vars[idx][2 * varidx + 1] + ' of ' + mechanism_names[idx] + ' vs Voltage (V)') show()
def chan_proto(chanparams, VDIVS=3000, VMIN=-100e-3, VMAX=50e-3, CAMIN=0, CAMAX=1, CADIVS=5000): lib = moose.Neutral('/library') chan = moose.HHChannel('/library/' + chanparams.name) # create the channel chan.Ek = chanparams.Erev chan.Xpower = chanparams.Xpow if chan.Xpower > 0: xGate = moose.HHGate(chan.path + '/gateX') # create the activation gating variable if chanparams.name == 'CaL': xGate.setupAlpha(chanparams.Xparam + (VDIVS, VMIN, VMAX)) #fix_singularities(chanparams.Xparam, xGate) elif chanparams.name == 'HCN': xGate.min = VMIN xGate.max = VMAX varray = np.linspace(VMIN, VMAX, VDIVS) qt = chanparams.Xparam.q10**((chanparams.Xparam.celsius - 33) / 10) inf_x = 1 / (1 + np.exp( -(varray - chanparams.Xparam.vhalfl) / chanparams.Xparam.kl)) a = np.exp(0.0378 * chanparams.Xparam.zetat * (varray - chanparams.Xparam.vhalft)) bett = np.exp(0.0378 * chanparams.Xparam.zetat * chanparams.Xparam.gmt * (varray - chanparams.Xparam.vhalft)) tau_x = bett / (chanparams.Xparam.qtl * qt * chanparams.Xparam.a0t * (1 + a)) xGate.tableA = inf_x / tau_x xGate.tableB = 1 / tau_x #setupAlpha automatically creates tables of a and b between VMIN and VMAX #elif chanparams.name == 'na': # make_sigmoid_gate(chanparams.Xparam,xGate,VDIVS = 3000, VMIN = -100e-3 , VMAX = 50e-3) else: xGate.setupAlpha(chanparams.Xparam + (VDIVS, VMIN, VMAX)) chan.Ypower = chanparams.Ypow if chan.Ypower > 0: #optional inactivation gate yGate = moose.HHGate(chan.path + '/gateY') #if chanparams.name == 'na': # make_sigmoid_gate(chanparams.Yparam,yGate,VDIVS = 3000, VMIN = -100e-3 , VMAX = 50e-3) if chanparams.name == 'CaN': yGate.min = VMIN yGate.max = VMAX varray = np.linspace(VMIN, VMAX, VDIVS) tau = sigmoid(varray, chanparams.Yparam.T_min, chanparams.Yparam.T_vdep, chanparams.Yparam.T_vhalf, chanparams.Yparam.T_vslope) minf = sigmoid(varray, chanparams.Yparam.SS_min, chanparams.Yparam.SS_vdep, chanparams.Yparam.SS_vhalf, chanparams.Yparam.SS_vslope) yGate.tableA = minf / tau yGate.tableB = 1 / tau else: yGate.setupAlpha(list(chanparams.Yparam) + [VDIVS, VMIN, VMAX]) if chanparams.Zpow > 0: chan.Zpower = chanparams.Zpow #normal channel stuff zgate = moose.HHGate(chan.path + '/gateZ') ca_array = np.linspace(CAMIN, CAMAX, CADIVS) zgate.min = CAMIN #specific to calcium dependent channels zgate.max = CAMAX caterm = (ca_array / chanparams.Zparam.Kd)**chanparams.Zparam.power inf_z = caterm / (1 + caterm) tau_z = chanparams.Zparam.tau * np.ones(len(ca_array)) zgate.tableA = inf_z / tau_z zgate.tableB = 1 / tau_z chan.useConcentration = True return chan
def alpha_m(self): if self.Xpower == 0: return numpy.array([]) return numpy.array(moose.HHGate('%s/gateX' % (self.path)).tableA)
def chan_proto(model, chanpath, params): log.info("{}: {}", chanpath, params) chan = moose.HHChannel(chanpath) chan.Xpower = params.channel.Xpow if params.channel.Xpow > 0: xGate = moose.HHGate(chan.path + '/gateX') if isinstance(params.X,AlphaBetaChannelParams): xGate.setupAlpha(params.X + [model.VDIVS, model.VMIN, model.VMAX]) fix_singularities(model, params.X, xGate) elif isinstance(params.X,StandardMooseTauInfChannelParams): xGate.setupTau(params.X + [model.VDIVS, model.VMIN, model.VMAX]) fix_singularities(model, params.X, xGate) elif isinstance(params.X,TauInfMinChannelParams): make_sigmoid_gate(model,params.X,xGate) elif isinstance(params.X,SSTauQuadraticChannelParams): make_quadratic_gate(model,params.X,xGate) chan.Ypower = params.channel.Ypow if params.channel.Ypow > 0: yGate = moose.HHGate(chan.path + '/gateY') if isinstance(params.Y,AlphaBetaChannelParams): yGate.setupAlpha(params.Y + [model.VDIVS, model.VMIN, model.VMAX]) fix_singularities(model, params.Y, yGate) elif isinstance(params.Y,StandardMooseTauInfChannelParams): yGate.setupTau(params.Y + [model.VDIVS, model.VMIN, model.VMAX]) fix_singularities(model, params.Y, yGate) elif isinstance(params.Y,TauInfMinChannelParams): make_sigmoid_gate(model,params.Y,yGate) elif isinstance(params.Y,SSTauQuadraticChannelParams): make_quadratic_gate(model,params.Y,yGate) if params.channel.Zpow > 0: chan.Zpower = params.channel.Zpow zGate = moose.HHGate(chan.path + '/gateZ') if params.Z.__class__==ZChannelParams: # ca_array = np.linspace(model.CAMIN, model.CAMAX, model.CADIVS) zGate.min = model.CAMIN zGate.max = model.CAMAX caterm = (ca_array/params.Z.Kd) ** params.Z.power inf_z = caterm / (1 + caterm) if params.Z.taumax>0: tauterm=(ca_array/params.Z.cahalf)**params.Z.tau_power taumax_z=(params.Z.taumax-params.Z.tau)/(1+tauterm) taumin_z= params.Z.tau * np.ones(len(ca_array)) tau_z = taumin_z+taumax_z else: tau_z = params.Z.tau * np.ones(len(ca_array)) # zGate.tableA = inf_z / tau_z zGate.tableB = 1 / tau_z chan.useConcentration = True else: chan.useConcentration = False if isinstance(params.Z,AlphaBetaChannelParams): zGate.setupAlpha(params.Z + [model.VDIVS, model.VMIN, model.VMAX]) fix_singularities(model, params.Z, zGate) elif isinstance(params.Z,StandardMooseTauInfChannelParams): zGate.setupTau(params.Z + [model.VDIVS, model.VMIN, model.VMAX]) fix_singularities(model, params.Z, zGate) elif isinstance(params.Z,TauInfMinChannelParams): make_sigmoid_gate(model,params.Z,zGate) elif isinstance(params.Z,SSTauQuadraticChannelParams): make_quadratic_gate(model,params.Z,zGate) chan.Ek = params.channel.Erev return chan
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 createChanProto(libraryName, channelParams, rateParams, CaParams = None, HCNParams = None): # Create a library to store the channel prototypes if not moose.exists(libraryName): lib = moose.Neutral(libraryName) else: lib = moose.element(libraryName) # Create the channel and set the powers and reversal potential channel = moose.HHChannel(lib.path + '/' + channelParams.name) channel.Ek = channelParams.Erev channel.Xpower = channelParams.Xpow channel.Ypower = channelParams.Ypow channel.Zpower = channelParams.Zpow # Define the activation gating kinetics if they exist if channel.Xpower > 0 and 'HCN' not in channelParams.name : xGate = moose.HHGate(channel.path + '/' + 'gateX') xGate.setupAlpha(channelParams.Xparam + rateParams) print channelParams.Xpow # Define custom activation gating kinetics if they exist (Hyperpolarized channel kinetics) if channel.Xpower > 0 and 'HCN' in channelParams.name : channel.Xpower = channelParams.Xpow xGate = moose.HHGate(channel.path + '/' + 'gateX') v_array = np.linspace(HCNParams[0], HCNParams[1], HCNParams[2]) xGate.min = HCNParams[0] xGate.max = HCNParams[1] # custom equation for HCN gating kinetics alpha = (channelParams.Xparam.alpha_0*np.exp((0.001)*-channelParams.Xparam.a*channelParams.Xparam.z \ *(v_array-channelParams.Xparam.Vhalf)*channelParams.Xparam.Fday \ /(channelParams.Xparam.R*(273.16 + channelParams.Xparam.T)))) print alpha beta = (channelParams.Xparam.alpha_0*np.exp((0.001)*(1-channelParams.Xparam.a) \ *channelParams.Xparam.z*(v_array-channelParams.Xparam.Vhalf)*channelParams.Xparam.Fday/ \ (channelParams.Xparam.R*(273.16 + channelParams.Xparam.T)))) print beta a = HCNParams[3]*alpha b = HCNParams[3]*beta inf_x = a/(a+b) tau_x = 1/(a+b) for i in tau_x: if i < 2: i = 2 else: i xGate.tableA = inf_x / tau_x xGate.tableB = 1 / tau_x print channelParams.Xpow # Define the inactivation gating kinetics if they exist if channel.Ypower > 0: yGate = moose.HHGate(channel.path + '/' + 'gateY') yGate.setupAlpha(channelParams.Yparam + rateParams) if channel.Zpower > 0: channel.Zpower = channelParams.Zpow ca_array = np.linspace(CaParams[0], CaParams[1], CaParams[2]) zGate = moose.HHGate(channel.path + '/' + 'gateZ') zGate.min = CaParams[0] zGate.max = CaParams[1] # custom equation for the Ca dynamics caterm = (ca_array/channelParams.Zparam.Kd) caterm = caterm**channelParams.Zparam.power inf_z = caterm/(1+caterm) tau_z = channelParams.Zparam.tau*np.ones(len(ca_array)) # How to fill the A and B tables with custom gating zGate.tableA = inf_z / tau_z #tableA is equivalent to alpha zGate.tableB = 1 / tau_z # tableB is equivalent to alpha+beta # Set this for z Gate channel to use concentration channel.useConcentration = True # Set the tick for the channel so that it is set appropriately when it # is copied to a channel from the library channel.tick = -1 return channel
def createChanProto(libraryName, channelParams, rateParams, CaParams = None): # Create a library to store the channel prototypes if not moose.exists(libraryName): lib = moose.Neutral(libraryName) else: lib = moose.element(libraryName) # Create the channel and set the powers and reversal potential channel = moose.HHChannel(lib.path + '/' + channelParams.name) channel.Ek = channelParams.Erev channel.Xpower = channelParams.Xpow channel.Ypower = channelParams.Ypow channel.Zpower = channelParams.Zpow # Define the activation gating kinetics if they exist if channel.Xpower > 0 and 'HCN' not in channelParams.name : xGate = moose.HHGate(channel.path + '/' + 'gateX') xGate.setupAlpha(channelParams.Xparam + rateParams) # Define custom activation gating kinetics if they exist (Hyperpolarized channel kinetics) if channel.Xpower > 0 and 'HCN' in channelParams.name : Fday = 9.648e4 R = 8.315 FbyRT= Fday/ \ (R*(273.16 + channelParams.Xparam.sim_temp)) channel.Xpower = channelParams.Xpow xGate = moose.HHGate(channel.path + '/' + 'gateX') v_array = np.linspace(rateParams[1], rateParams[2], rateParams[0]+1) xGate.min = rateParams[1] xGate.max = rateParams[2] # custom equation for HCN gating kinetics alpha = (channelParams.Xparam.alpha_0*np.exp(-channelParams.Xparam.a*channelParams.Xparam.z \ *(v_array-channelParams.Xparam.Vhalf)*FbyRT)) beta = (channelParams.Xparam.alpha_0*np.exp((1-channelParams.Xparam.a) \ *channelParams.Xparam.z*(v_array-channelParams.Xparam.Vhalf)*FbyRT)) q10 = channelParams.Xparam.q10**((channelParams.Xparam.sim_temp-channelParams.Xparam.exp_temp)/10) inf_x = alpha/(alpha+beta) tau_x = 1/(q10*(alpha+beta)) #tau_x = [tau_x if tau_x > 2e-3 else 2e-3 for tau_x in tau_x] tau_x = np.array(tau_x) xGate.tableA = inf_x /tau_x xGate.tableB = 1 / tau_x # Define the inactivation gating kinetics if they exist if channel.Ypower > 0: yGate = moose.HHGate(channel.path + '/' + 'gateY') yGate.setupAlpha(channelParams.Yparam + rateParams) if channel.Zpower > 0: channel.Zpower = channelParams.Zpow ca_array = np.linspace(CaParams[0], CaParams[1], CaParams[2]) zGate = moose.HHGate(channel.path + '/' + 'gateZ') zGate.min = CaParams[0] zGate.max = CaParams[1] # custom equation for the Ca dynamics caterm = (ca_array/channelParams.Zparam.Kd) caterm = caterm**channelParams.Zparam.power inf_z = caterm/(1+caterm) tau_z = channelParams.Zparam.tau*np.ones(len(ca_array)) # How to fill the A and B tables with custom gating zGate.tableA = inf_z / tau_z #tableA is equivalent to alpha zGate.tableB = 1 / tau_z # tableB is equivalent to alpha+beta # Set this for z Gate channel to use concentration channel.useConcentration = True # Set the tick for the channel so that it is set appropriately when it # is copied to a channel from the library channel.tick = -1 return channel