def __init__(self, N, clock, params=default_params): # x=input # r=firing rate # a=adaptation signal # e=efficacy # tau_r1 = firing rate rise time constant # tau_r2 = firing rate decay rate # tau_ar = adaptation rate # tau_a = adaptation recovery rate # eta = rate - adaptation gain eqs=Equations(''' dr/dt=x/tau_r1-r/tau_r2 : 1 da/dt=(eta*r)/tau_ar-a/tau_a : 1 e=1.0-a : 1 tau_a : second tau_r1 : second tau_r2 : second tau_ar : second eta : 1 x : 1 ''') NeuronGroup.__init__(self, N, model=eqs, compile=True, freeze=True, clock=clock) self.N=N self.params=params self.tau_a=self.params.tau_a self.tau_r1=self.params.tau_r1 self.tau_r2=self.params.tau_r2 self.tau_ar=self.params.tau_ar self.eta=self.params.eta
def __init__(self, P, V, I, clock=None): eqs = Equations(''' record : units_record command : units_command ''', units_record=P.unit(V), units_command=P.unit(I)) NeuronGroup.__init__(self, len(P), model=eqs, clock=clock) self._P = P self._V = V self._I = I
def __init__(self, P, V, I, clock=None): eqs = Equations(''' record : units_record command : units_command ''', units_record=P.unit(V), units_command=P.unit(I)) NeuronGroup.__init__(self, len(P), model=eqs, clock=clock) self._P = P self._V = V self._I = I
def __init__(self, morphology=None, model=None, threshold=None, reset=NoReset(), refractory=0 * ms, level=0, clock=None, unit_checking=True, compile=False, freeze=False, cm=0.9 * uF / cm ** 2, Ri=150 * ohm * cm): clock = guess_clock(clock) N = len(morphology) # number of compartments # Equations for morphology eqs_morphology = Equations(""" diameter : um length : um x : um y : um z : um area : um**2 """) # Create the state updater if isinstance(model, str): model = Equations(model, level=level + 1) model += Equations(''' v:volt # membrane potential #Im:amp/cm**2 # membrane current (should we have it?) ''') full_model = model + eqs_morphology Group.__init__(self, full_model, N, unit_checking=unit_checking) self._eqs = model self._state_updater = SpatialStateUpdater(model, clock) var_names = full_model._diffeq_names self.cm = cm # could be a vector? self.Ri = Ri S0 = {} # Fill missing units for key, value in full_model._units.iteritems(): if not key in S0: S0[key] = 0 * value self._S0 = [0] * len(var_names) for var, i in zip(var_names, count()): self._S0[i] = S0[var] NeuronGroup.__init__(self, N, model=self._state_updater, threshold=threshold, reset=reset, refractory=refractory, level=level + 1, clock=clock, unit_checking=unit_checking) # Insert morphology self.morphology = morphology self.morphology.compress(diameter=self.diameter, length=self.length, x=self.x, y=self.y, z=self.z, area=self.area)
def __init__(self, params=default_params, pyr_params=pyr_params(), inh_params=inh_params(), background_input=None, task_inputs=None, clock=defaultclock): self.params=params self.pyr_params=pyr_params self.inh_params=inh_params self.background_input=background_input self.task_inputs=task_inputs ## Set up equations # Exponential integrate-and-fire neuron eqs = exp_IF(params.C, params.gL, params.EL, params.VT, params.DeltaT) eqs += Equations('g_muscimol : nS') # AMPA conductance - recurrent input current eqs += exp_synapse('g_ampa_r', params.tau_ampa, siemens) eqs += Current('I_ampa_r=g_ampa_r*(E-vm): amp', E=params.E_ampa) # AMPA conductance - background input current eqs += exp_synapse('g_ampa_b', params.tau_ampa, siemens) eqs += Current('I_ampa_b=g_ampa_b*(E-vm): amp', E=params.E_ampa) # AMPA conductance - task input current eqs += exp_synapse('g_ampa_x', params.tau_ampa, siemens) eqs += Current('I_ampa_x=g_ampa_x*(E-vm): amp', E=params.E_ampa) # Voltage-dependent NMDA conductance eqs += biexp_synapse('g_nmda', params.tau1_nmda, params.tau2_nmda, siemens) eqs += Equations('g_V = 1/(1+(Mg/3.57)*exp(-0.062 *vm/mV)) : 1 ', Mg=params.Mg) eqs += Current('I_nmda=g_V*g_nmda*(E-vm): amp', E=params.E_nmda) # GABA-A conductance eqs += exp_synapse('g_gaba_a', params.tau_gaba_a, siemens) eqs += Current('I_gaba_a=g_gaba_a*(E-vm): amp', E=params.E_gaba_a) eqs +=InjectedCurrent('I_dcs: amp') NeuronGroup.__init__(self, params.network_group_size, model=eqs, threshold=-20*mV, refractory=1*ms, reset=params.Vr, compile=True, freeze=True, clock=clock) self.init_subpopulations() self.init_connectivity(clock)
def __init__(self, source, n_per_channel=1, params=None): params = ZhangSynapse._get_parameters(params) c_0, c_1 = params['c_0'], params['c_1'] s_0, s_1 = params['s_0'], params['s_1'] R_A = params['R_A'] eqs = ''' # time-varying discharge rate, input into this model s : Hz # discharge-history effect (Equation 20 in differential equation form) H = c_0*e_0 + c_1*e_1 : 1 de_0/dt = -e_0/s_0 : 1 de_1/dt = -e_1/s_1 : 1 # final time-varying discharge rate for the Poisson process, equation 19 R = s * (1 - H) : Hz ''' def reset_func(P, spikes): P.e_0[spikes] = 1.0 P.e_1[spikes] = 1.0 # make sure that the s value is first updated in # ZhangSynapseRate, then this NeuronGroup is # updated clock=Clock(dt=source.clock.dt, t=source.clock.t, order=source.clock.order + 1) @network_operation(clock=clock, when='start') def distribute_input(): self.s[:] = source.s.repeat(n_per_channel) NeuronGroup.__init__(self, len(source) * n_per_channel, model=eqs, threshold=PoissonThreshold('R'), reset=CustomRefractoriness(resetfun=reset_func, period=R_A), clock=clock ) self.contained_objects += [distribute_input]
def __init__(self, morphology=None, model=None, threshold=None, reset=NoReset(), refractory=0 * ms, level=0, clock=None, unit_checking=True, compile=False, freeze=False, implicit=True, Cm=0.9 * uF / cm**2, Ri=150 * ohm * cm, bc_type=2, diffeq_nonzero=True): clock = guess_clock(clock) N = len(morphology) # number of compartments if isinstance(model, str): model = Equations(model, level=level + 1) model += Equations(''' v:volt # membrane potential ''') # Process model equations (Im) to extract total conductance and the remaining current if use_sympy: try: membrane_eq = model._string['Im'] # the membrane equation except: raise TypeError, "The transmembrane current Im must be defined" # Check conditional linearity ids = get_identifiers(membrane_eq) _namespace = dict.fromkeys( ids, 1. ) # there is a possibility of problems here (division by zero) _namespace['v'] = AffineFunction() eval(membrane_eq, model._namespace['v'], _namespace) try: eval(membrane_eq, model._namespace['v'], _namespace) except: # not linear raise TypeError, "The membrane current must be linear with respect to v" # Extracts the total conductance from Im, and the remaining current z = symbolic_eval(membrane_eq) symbol_v = sympy.Symbol('v') b = z.subs(symbol_v, 0) a = -sympy.simplify(z.subs(symbol_v, 1) - b) gtot_str = "_gtot=" + str(a) + ": siemens/cm**2" I0_str = "_I0=" + str(b) + ": amp/cm**2" model += Equations( gtot_str + "\n" + I0_str, level=level + 1) # better: explicit insertion with namespace of v else: raise TypeError, "The Sympy package must be installed for SpatialNeuron" # Equations for morphology (isn't it a duplicate??) eqs_morphology = Equations(""" diameter : um length : um x : um y : um z : um area : um**2 """) full_model = model + eqs_morphology NeuronGroup.__init__(self, N, model=full_model, threshold=threshold, reset=reset, refractory=refractory, level=level + 1, clock=clock, unit_checking=unit_checking, implicit=implicit) self.model_with_diffeq_nonzero = diffeq_nonzero self._state_updater = SpatialStateUpdater(self, clock) self.Cm = ones(len(self)) * Cm self.Ri = Ri self.bc_type = bc_type #default boundary condition on leaves self.bc = ones(len(self)) # boundary conditions on branch points self.changed = True # Insert morphology self.morphology = morphology self.morphology.compress(diameter=self.diameter, length=self.length, x=self.x, y=self.y, z=self.z, area=self.area)
def __init__(self, params=default_params, pyr_params=pyr_params(), inh_params=inh_params(), plasticity_params=plasticity_params(), background_input=None, task_inputs=None, clock=defaultclock): self.params = params self.pyr_params = pyr_params self.inh_params = inh_params self.plasticity_params = plasticity_params self.background_input = background_input self.task_inputs = task_inputs ## Set up equations # Exponential integrate-and-fire neuron eqs = exp_IF(params.C, params.gL, params.EL, params.VT, params.DeltaT) eqs += Equations('g_muscimol : nS') # AMPA conductance - recurrent input current eqs += exp_synapse('g_ampa_r', params.tau_ampa, siemens) eqs += Current('I_ampa_r=g_ampa_r*(E-vm): amp', E=params.E_ampa) # AMPA conductance - background input current eqs += exp_synapse('g_ampa_b', params.tau_ampa, siemens) eqs += Current('I_ampa_b=g_ampa_b*(E-vm): amp', E=params.E_ampa) # AMPA conductance - task input current eqs += exp_synapse('g_ampa_x', params.tau_ampa, siemens) eqs += Current('I_ampa_x=g_ampa_x*(E-vm): amp', E=params.E_ampa) # Voltage-dependent NMDA conductance eqs += biexp_synapse('g_nmda', params.tau1_nmda, params.tau2_nmda, siemens) eqs += Equations('g_V = 1/(1+(Mg/3.57)*exp(-0.062 *vm/mV)) : 1 ', Mg=params.Mg) eqs += Current('I_nmda=g_V*g_nmda*(E-vm): amp', E=params.E_nmda) # GABA-A conductance eqs += exp_synapse('g_gaba_a', params.tau_gaba_a, siemens) eqs += Current('I_gaba_a=(g_gaba_a+g_muscimol)*(E-vm): amp', E=params.E_gaba_a) eqs += InjectedCurrent('I_dcs: amp') # Total synaptic conductance eqs += Equations( 'g_syn=g_ampa_r+g_ampa_x+g_ampa_b+g_V*g_nmda+g_gaba_a : siemens') eqs += Equations( 'g_syn_exc=g_ampa_r+g_ampa_x+g_ampa_b+g_V*g_nmda : siemens') # Total synaptic current eqs += Equations( 'I_abs=(I_ampa_r**2)**.5+(I_ampa_b**2)**.5+(I_ampa_x**2)**.5+(I_nmda**2)**.5+(I_gaba_a**2)**.5 : amp' ) NeuronGroup.__init__(self, params.network_group_size, model=eqs, threshold=-20 * mV, refractory=1 * ms, reset=params.Vr, compile=True, freeze=True, clock=clock) self.init_subpopulations() self.init_connectivity(clock)
def __init__(self, morphology=None, model=None, threshold=None, reset=NoReset(), refractory=0 * ms, level=0, clock=None, unit_checking=True, compile=False, freeze=False, implicit=True, Cm=0.9 * uF / cm ** 2, Ri=150 * ohm * cm, bc_type = 2, diffeq_nonzero=True): clock = guess_clock(clock) N = len(morphology) # number of compartments if isinstance(model, str): model = Equations(model, level=level + 1) model += Equations(''' v:volt # membrane potential ''') # Process model equations (Im) to extract total conductance and the remaining current if use_sympy: try: membrane_eq=model._string['Im'] # the membrane equation except: raise TypeError,"The transmembrane current Im must be defined" # Check conditional linearity ids=get_identifiers(membrane_eq) _namespace=dict.fromkeys(ids,1.) # there is a possibility of problems here (division by zero) _namespace['v']=AffineFunction() eval(membrane_eq,model._namespace['v'],_namespace) try: eval(membrane_eq,model._namespace['v'],_namespace) except: # not linear raise TypeError,"The membrane current must be linear with respect to v" # Extracts the total conductance from Im, and the remaining current z=symbolic_eval(membrane_eq) symbol_v=sympy.Symbol('v') b=z.subs(symbol_v,0) a=-sympy.simplify(z.subs(symbol_v,1)-b) gtot_str="_gtot="+str(a)+": siemens/cm**2" I0_str="_I0="+str(b)+": amp/cm**2" model+=Equations(gtot_str+"\n"+I0_str,level=level+1) # better: explicit insertion with namespace of v else: raise TypeError,"The Sympy package must be installed for SpatialNeuron" # Equations for morphology (isn't it a duplicate??) eqs_morphology = Equations(""" diameter : um length : um x : um y : um z : um area : um**2 """) full_model = model + eqs_morphology NeuronGroup.__init__(self, N, model=full_model, threshold=threshold, reset=reset, refractory=refractory, level=level + 1, clock=clock, unit_checking=unit_checking, implicit=implicit) self.model_with_diffeq_nonzero = diffeq_nonzero self._state_updater = SpatialStateUpdater(self, clock) self.Cm = ones(len(self))*Cm self.Ri = Ri self.bc_type = bc_type #default boundary condition on leaves self.bc = ones(len(self)) # boundary conditions on branch points self.changed = True # Insert morphology self.morphology = morphology self.morphology.compress(diameter=self.diameter, length=self.length, x=self.x, y=self.y, z=self.z, area=self.area)
def __init__(self, source, target = None, model = None, pre = None, post = None, max_delay = 0*ms, level = 0, clock = None,code_namespace=None, unit_checking = True, method = None, freeze = False, implicit = False, order = 1): # model (state updater) related target=target or source # default is target=source # Check clocks. For the moment we enforce the same clocks for all objects clock = clock or source.clock if source.clock!=target.clock: raise ValueError,"Source and target groups must have the same clock" if pre is None: pre_list=[] elif isSequenceType(pre) and not isinstance(pre,str): # a list of pre codes pre_list=pre else: pre_list=[pre] pre_list=[flattened_docstring(pre) for pre in pre_list] if post is not None: post=flattened_docstring(post) # Pre and postsynaptic indexes (synapse -> pre/post) self.presynaptic=DynamicArray1D(0,dtype=smallest_inttype(len(source))) # this should depend on number of neurons self.postsynaptic=DynamicArray1D(0,dtype=smallest_inttype(len(target))) # this should depend on number of neurons if not isinstance(model,SynapticEquations): model=SynapticEquations(model,level=level+1) # Insert the lastupdate variable if necessary (if it is mentioned in pre/post, or if there is event-driven code) expr=re.compile(r'\blastupdate\b') if (len(model._eventdriven)>0) or \ any([expr.search(pre) for pre in pre_list]) or \ (post is not None and expr.search(post) is not None): model+='\nlastupdate : second\n' pre_list=[pre+'\nlastupdate=t\n' for pre in pre_list] if post is not None: post=post+'\nlastupdate=t\n' # Identify pre and post variables in the model string # They are identified by _pre and _post suffixes # or no suffix for postsynaptic variables ids=set() for RHS in model._string.itervalues(): ids.update(get_identifiers(RHS)) pre_ids = [id[:-4] for id in ids if id[-4:]=='_pre'] post_ids = [id[:-5] for id in ids if id[-5:]=='_post'] post_vars = [var for var in source.var_index if isinstance(var,str)] # postsynaptic variables post_ids2 = list(ids.intersection(set(post_vars))) # post variables without the _post suffix # remember whether our equations refer to any variables in the pre- or # postsynaptic group. This is important for the state-updater, e.g. the # equations can no longer be solved as linear equations. model.refers_others = (len(pre_ids) + len(post_ids) + len(post_ids2) > 0) # Insert static equations for pre and post variables S=self for name in pre_ids: model.add_eq(name+'_pre', 'S.source.'+name+'[S.presynaptic[:]]', source.unit(name), global_namespace={'S':S}) for name in post_ids: model.add_eq(name+'_post', 'S.target.'+name+'[S.postsynaptic[:]]', target.unit(name), global_namespace={'S':S}) for name in post_ids2: # we have to change the name of the variable to avoid problems with equation processing if name not in model._string: # check that it is not already defined model.add_eq(name, 'S.target.state_(__'+name+')[S.postsynaptic[:]]', target.unit(name), global_namespace={'S':S,'__'+name:name}) self.source=source self.target=target NeuronGroup.__init__(self, 0,model=model,clock=clock,level=level+1,unit_checking=unit_checking,method=method,freeze=freeze,implicit=implicit,order=order) ''' At this point we have: * a state matrix _S with all variables * units, state dictionary with each value being a row of _S + the static equations * subgroups of synapses * link_var (i.e. we can link two synapses objects) * __len__ * __setattr__: we can write S.w=array of values * var_index is a dictionary from names to row index in _S * num_states() Things we have that we don't want: * LS structure (but it will not be filled since the object does not spike) * (from Group) __getattr_ needs to be rewritten * a complete state updater, but we need to extract parameters and event-driven parts * The state matrix is not dynamic Things we may need to add: * _pre and _post suffixes ''' self._iscompressed=False # True if compress() has already been called # Look for event-driven code in the differential equations if use_sympy: eqs=self._eqs # an Equations object #vars=eqs._diffeq_names_nonzero # Dynamic variables vars=eqs._eventdriven.keys() var_set=set(vars) for var,RHS in eqs._eventdriven.iteritems(): ids=get_identifiers(RHS) if len(set(list(ids)+[var]).intersection(var_set))==1: # no external dynamic variable # Now we test if it is a linear equation _namespace=dict.fromkeys(ids,1.) # there is a possibility of problems here (division by zero) # plus units problems? (maybe not since these are identifiers too) # another option is to use random numbers, but that doesn't solve all problems _namespace[var]=AffineFunction() try: eval(RHS,eqs._namespace[var],_namespace) except: # not linear raise TypeError,"Cannot turn equation for "+var+" into event-driven code" z=symbolic_eval(RHS) symbol_var=sympy.Symbol(var) symbol_t=sympy.Symbol('t')-sympy.Symbol('lastupdate') b=z.subs(symbol_var,0) a=sympy.simplify(z.subs(symbol_var,1)-b) if a==0: expr=symbol_var+b*symbol_t else: expr=-b/a+sympy.exp(a*symbol_t)*(symbol_var+b/a) expr=var+'='+str(expr) # Replace pre and post code # N.B.: the differential equations are kept, we will probably want to remove them! pre_list=[expr+'\n'+pre for pre in pre_list] if post is not None: post=expr+'\n'+post else: raise TypeError,"Cannot turn equation for "+var+" into event-driven code" elif len(self._eqs._eventdriven)>0: raise TypeError,"The Sympy package must be installed to produce event-driven code" if len(self._eqs._diffeq_names_nonzero)==0: self._state_updater=None # Set last spike to -infinity if 'lastupdate' in self.var_index: self.lastupdate=-1e6 # _S is turned to a dynamic array - OK this is probably not good! we may lose references at this point S=self._S self._S=DynamicArray(S.shape) self._S[:]=S # Pre and postsynaptic delays (synapse -> delay_pre/delay_post) self._delay_pre=[DynamicArray1D(len(self),dtype=np.int16) for _ in pre_list] # max 32767 delays self._delay_post=DynamicArray1D(len(self),dtype=np.int16) # Actually only useful if there is a post code! # Pre and postsynaptic synapses (i->synapse indexes) max_synapses=2147483647 # it could be explicitly reduced by a keyword # We use a loop instead of *, otherwise only 1 dynamic array is created self.synapses_pre=[DynamicArray1D(0,dtype=smallest_inttype(max_synapses)) for _ in range(len(self.source))] self.synapses_post=[DynamicArray1D(0,dtype=smallest_inttype(max_synapses)) for _ in range(len(self.target))] # Code generation self._binomial = lambda n,p:np.random.binomial(np.array(n,dtype=int),p) self.contained_objects = [] self.codes=[] self.namespaces=[] self.queues=[] for i,pre in enumerate(pre_list): code,_namespace=self.generate_code(pre,level+1,code_namespace=code_namespace) self.codes.append(code) self.namespaces.append(_namespace) self.queues.append(SpikeQueue(self.source, self.synapses_pre, self._delay_pre[i], max_delay = max_delay)) if post is not None: code,_namespace=self.generate_code(post,level+1,direct=True,code_namespace=code_namespace) self.codes.append(code) self.namespaces.append(_namespace) self.queues.append(SpikeQueue(self.target, self.synapses_post, self._delay_post, max_delay = max_delay)) self.queues_namespaces_codes = zip(self.queues, self.namespaces, self.codes) self.contained_objects+=self.queues
def __init__(self, morphology=None, model=None, threshold=None, reset=NoReset(), refractory=0 * ms, level=0, clock=None, unit_checking=True, compile=False, freeze=False, Cm=0.9 * uF / cm ** 2, Ri=150 * ohm * cm): clock = guess_clock(clock) N = len(morphology) # number of compartments if isinstance(model, str): model = Equations(model, level=level + 1) model += Equations(''' v:volt # membrane potential ''') # Process model equations (Im) to extract total conductance and the remaining current if use_sympy: try: membrane_eq=model._string['Im'] # the membrane equation except: raise TypeError,"The transmembrane current Im must be defined" # Check conditional linearity ids=get_identifiers(membrane_eq) _namespace=dict.fromkeys(ids,1.) # there is a possibility of problems here (division by zero) _namespace['v']=AffineFunction() eval(membrane_eq,model._namespace['v'],_namespace) try: eval(membrane_eq,model._namespace['v'],_namespace) except: # not linear raise TypeError,"The membrane current must be linear with respect to v" # Extracts the total conductance from Im, and the remaining current z=symbolic_eval(membrane_eq) symbol_v=sympy.Symbol('v') b=z.subs(symbol_v,0) a=-sympy.simplify(z.subs(symbol_v,1)-b) gtot_str="_gtot="+str(a)+": siemens/cm**2" I0_str="_I0="+str(b)+": amp/cm**2" model+=Equations(gtot_str+"\n"+I0_str,level=level+1) # better: explicit insertion with namespace of v else: raise TypeError,"The Sympy package must be installed for SpatialNeuron" # Equations for morphology (isn't it a duplicate??) eqs_morphology = Equations(""" diameter : um length : um x : um y : um z : um area : um**2 """) full_model = model + eqs_morphology # Create the state updater NeuronGroup.__init__(self, N, model=full_model, threshold=threshold, reset=reset, refractory=refractory, level=level + 1, clock=clock, unit_checking=unit_checking, implicit=True) #Group.__init__(self, full_model, N, unit_checking=unit_checking, level=level+1) #self._eqs = model #var_names = full_model._diffeq_names self.Cm = Cm # could be a vector? self.Ri = Ri self._state_updater = SpatialStateUpdater(self, clock) #S0 = {} # Fill missing units #for key, value in full_model._units.iteritems(): # if not key in S0: # S0[key] = 0 * value #self._S0 = [0] * len(var_names) #for var, i in zip(var_names, count()): # self._S0[i] = S0[var] # Insert morphology self.morphology = morphology self.morphology.compress(diameter=self.diameter, length=self.length, x=self.x, y=self.y, z=self.z, area=self.area)
def __init__(self, morphology=None, model=None, threshold=None, reset=NoReset(), refractory=0 * ms, level=0, clock=None, unit_checking=True, compile=False, freeze=False, Cm=0.9 * uF / cm**2, Ri=150 * ohm * cm): clock = guess_clock(clock) N = len(morphology) # number of compartments if isinstance(model, str): model = Equations(model, level=level + 1) model += Equations(''' v:volt # membrane potential ''') # Process model equations (Im) to extract total conductance and the remaining current if use_sympy: try: membrane_eq = model._string['Im'] # the membrane equation except: raise TypeError, "The transmembrane current Im must be defined" # Check conditional linearity ids = get_identifiers(membrane_eq) _namespace = dict.fromkeys( ids, 1. ) # there is a possibility of problems here (division by zero) _namespace['v'] = AffineFunction() eval(membrane_eq, model._namespace['v'], _namespace) try: eval(membrane_eq, model._namespace['v'], _namespace) except: # not linear raise TypeError, "The membrane current must be linear with respect to v" # Extracts the total conductance from Im, and the remaining current z = symbolic_eval(membrane_eq) symbol_v = sympy.Symbol('v') b = z.subs(symbol_v, 0) a = -sympy.simplify(z.subs(symbol_v, 1) - b) gtot_str = "_gtot=" + str(a) + ": siemens/cm**2" I0_str = "_I0=" + str(b) + ": amp/cm**2" model += Equations( gtot_str + "\n" + I0_str, level=level + 1) # better: explicit insertion with namespace of v else: raise TypeError, "The Sympy package must be installed for SpatialNeuron" # Equations for morphology (isn't it a duplicate??) eqs_morphology = Equations(""" diameter : um length : um x : um y : um z : um area : um**2 """) full_model = model + eqs_morphology # Create the state updater NeuronGroup.__init__(self, N, model=full_model, threshold=threshold, reset=reset, refractory=refractory, level=level + 1, clock=clock, unit_checking=unit_checking, implicit=True) #Group.__init__(self, full_model, N, unit_checking=unit_checking, level=level+1) #self._eqs = model #var_names = full_model._diffeq_names self.Cm = Cm # could be a vector? self.Ri = Ri self._state_updater = SpatialStateUpdater(self, clock) #S0 = {} # Fill missing units #for key, value in full_model._units.iteritems(): # if not key in S0: # S0[key] = 0 * value #self._S0 = [0] * len(var_names) #for var, i in zip(var_names, count()): # self._S0[i] = S0[var] # Insert morphology self.morphology = morphology self.morphology.compress(diameter=self.diameter, length=self.length, x=self.x, y=self.y, z=self.z, area=self.area)
def __init__( self, params=default_params, pyr_params=pyr_params(), inh_params=inh_params(), plasticity_params=plasticity_params(), background_input=None, task_inputs=None, clock=defaultclock, ): self.params = params self.pyr_params = pyr_params self.inh_params = inh_params self.plasticity_params = plasticity_params self.background_input = background_input self.task_inputs = task_inputs ## Set up equations # Exponential integrate-and-fire neuron eqs = exp_IF(params.C, params.gL, params.EL, params.VT, params.DeltaT) eqs += Equations("g_muscimol : nS") # AMPA conductance - recurrent input current eqs += exp_synapse("g_ampa_r", params.tau_ampa, siemens) eqs += Current("I_ampa_r=g_ampa_r*(E-vm): amp", E=params.E_ampa) # AMPA conductance - background input current eqs += exp_synapse("g_ampa_b", params.tau_ampa, siemens) eqs += Current("I_ampa_b=g_ampa_b*(E-vm): amp", E=params.E_ampa) # AMPA conductance - task input current eqs += exp_synapse("g_ampa_x", params.tau_ampa, siemens) eqs += Current("I_ampa_x=g_ampa_x*(E-vm): amp", E=params.E_ampa) # Voltage-dependent NMDA conductance eqs += biexp_synapse("g_nmda", params.tau1_nmda, params.tau2_nmda, siemens) eqs += Equations("g_V = 1/(1+(Mg/3.57)*exp(-0.062 *vm/mV)) : 1 ", Mg=params.Mg) eqs += Current("I_nmda=g_V*g_nmda*(E-vm): amp", E=params.E_nmda) # GABA-A conductance eqs += exp_synapse("g_gaba_a", params.tau_gaba_a, siemens) eqs += Current("I_gaba_a=(g_gaba_a+g_muscimol)*(E-vm): amp", E=params.E_gaba_a) eqs += InjectedCurrent("I_dcs: amp") # Total synaptic conductance eqs += Equations("g_syn=g_ampa_r+g_ampa_x+g_ampa_b+g_V*g_nmda+g_gaba_a : siemens") eqs += Equations("g_syn_exc=g_ampa_r+g_ampa_x+g_ampa_b+g_V*g_nmda : siemens") # Total synaptic current eqs += Equations( "I_abs=(I_ampa_r**2)**.5+(I_ampa_b**2)**.5+(I_ampa_x**2)**.5+(I_nmda**2)**.5+(I_gaba_a**2)**.5 : amp" ) NeuronGroup.__init__( self, params.network_group_size, model=eqs, threshold=-20 * mV, refractory=1 * ms, reset=params.Vr, compile=True, freeze=True, clock=clock, ) self.init_subpopulations() self.init_connectivity(clock)