def before_run(self, run_namespace=None, level=0): # execute code to initalize the spike queue if self._initialise_queue_codeobj is None: self._initialise_queue_codeobj = create_runner_codeobj(self, '', # no code, 'synapses_initialise_queue', name=self.name+'_initialise_queue', check_units=False, additional_variables=self.variables, run_namespace=run_namespace, level=level+1) self._initialise_queue_codeobj() CodeRunner.before_run(self, run_namespace, level=level+1) # we insert rather than replace because CodeRunner puts a CodeObject in updaters already if self._pushspikes_codeobj is None: self._pushspikes_codeobj = create_runner_codeobj(self, '', # no code 'synapses_push_spikes', name=self.name+'_push_spikes', check_units=False, additional_variables=self.variables, run_namespace=run_namespace, level=level+1) self._code_objects.insert(0, weakref.proxy(self._pushspikes_codeobj))
def before_run(self, run_namespace=None, level=0): # execute code to initalize the spike queue if self._initialise_queue_codeobj is None: self._initialise_queue_codeobj = create_runner_codeobj( self, '', # no code, 'synapses_initialise_queue', name=self.name + '_initialise_queue', check_units=False, additional_variables=self.variables, run_namespace=run_namespace, level=level + 1) self._initialise_queue_codeobj() CodeRunner.before_run(self, run_namespace, level=level + 1) # we insert rather than replace because CodeRunner puts a CodeObject in updaters already if self._pushspikes_codeobj is None: self._pushspikes_codeobj = create_runner_codeobj( self, '', # no code 'synapses_push_spikes', name=self.name + '_push_spikes', check_units=False, additional_variables=self.variables, run_namespace=run_namespace, level=level + 1) self._code_objects.insert(0, weakref.proxy(self._pushspikes_codeobj))
def before_run(self, namespace): # Some dummy code so that code generation takes care of the indexing # and subexpressions code = ['_to_record_%s = %s' % (v, v) for v in self.record_variables] code = '\n'.join(code) for varname in self.record_variables: var = self.source.variables[varname] self.variables.add_auxiliary_variable('_to_record_' + varname, unit=var.unit, dtype=var.dtype, scalar=var.scalar, is_bool=var.is_bool) recorded_variables = dict([(name, self.variables['_recorded_'+name]) for name in self.record_variables]) recorded_names = ['_recorded_'+name for name in self.record_variables] self.codeobj = create_runner_codeobj(self.source, code, 'statemonitor', name=self.name+'_codeobject*', needed_variables=recorded_names, additional_variables=self.variables, additional_namespace=namespace, template_kwds={'_recorded_variables': recorded_variables}, check_units=False) self._code_objects[:] = [weakref.proxy(self.codeobj)]
def __getitem__(self, item): if isinstance(item, basestring): variables = Variables(None) variables.add_auxiliary_variable('_indices', unit=Unit(1), dtype=np.int32) variables.add_auxiliary_variable('_cond', unit=Unit(1), dtype=np.bool) abstract_code = '_cond = ' + item check_code_units(abstract_code, self.group, additional_variables=variables, level=1) from brian2.devices.device import get_default_codeobject_class codeobj = create_runner_codeobj( self.group, abstract_code, 'group_get_indices', additional_variables=variables, level=1, codeobj_class=get_default_codeobject_class( 'codegen.string_expression_target')) return codeobj() else: return self.indices(item)
def create_default_code_object(self, run_namespace): self.update_abstract_code(run_namespace=run_namespace) # If the CodeRunner has variables, add them if hasattr(self, 'variables'): additional_variables = self.variables else: additional_variables = None if not self.generate_empty_code and len(self.abstract_code) == 0: self.codeobj = None else: self.codeobj = create_runner_codeobj(group=self.group, code=self.abstract_code, user_code=self.user_code, template_name=self.template, name=f"{self.name}_codeobject*", check_units=self.check_units, additional_variables=additional_variables, needed_variables=self.needed_variables, run_namespace=run_namespace, template_kwds=self.template_kwds, override_conditional_write=self.override_conditional_write, codeobj_class=self.codeobj_class ) return self.codeobj
def before_run(self, run_namespace): self.update_abstract_code(run_namespace=run_namespace) # If the CodeRunner has variables, add them if hasattr(self, 'variables'): additional_variables = self.variables else: additional_variables = None if not self.generate_empty_code and len(self.abstract_code) == 0: self.codeobj = None self.code_objects[:] = [] else: self.codeobj = create_runner_codeobj(group=self.group, code=self.abstract_code, user_code=self.user_code, template_name=self.template, name=self.name+'_codeobject*', check_units=self.check_units, additional_variables=additional_variables, needed_variables=self.needed_variables, run_namespace=run_namespace, template_kwds=self.template_kwds, override_conditional_write=self.override_conditional_write, codeobj_class=self.codeobj_class ) self.code_objects[:] = [weakref.proxy(self.codeobj)]
def before_run(self, run_namespace): self.update_abstract_code(run_namespace=run_namespace) # If the CodeRunner has variables, add them if hasattr(self, 'variables'): additional_variables = self.variables else: additional_variables = None if not self.generate_empty_code and len(self.abstract_code) == 0: self.codeobj = None self.code_objects[:] = [] else: self.codeobj = create_runner_codeobj( group=self.group, code=self.abstract_code, user_code=self.user_code, template_name=self.template, name=self.name + '_codeobject*', check_units=self.check_units, additional_variables=additional_variables, needed_variables=self.needed_variables, run_namespace=run_namespace, template_kwds=self.template_kwds, override_conditional_write=self.override_conditional_write, codeobj_class=self.codeobj_class) self.code_objects[:] = [weakref.proxy(self.codeobj)]
def get_with_expression(self, variable_name, variable, code, level=0, run_namespace=None): ''' Gets a variable using a string expression. Is called by `VariableView.get_item` for statements such as ``print G.v['g_syn > 0']``. Parameters ---------- variable_name : str The name of the variable in its context (e.g. ``'g_post'`` for a variable with name ``'g'``) variable : `ArrayVariable` The `ArrayVariable` object for the variable to be set code : str An expression that states a condition for elements that should be selected. Can contain references to indices, such as ``i`` or ``j`` and to state variables. For example: ``'i>3 and v>0*mV'``. level : int, optional How much farther to go up in the stack to find the implicit namespace (if used, see `run_namespace`). run_namespace : dict-like, optional An additional namespace that is used for variable lookup (if not defined, the implicit namespace of local variables is used). ''' if variable.scalar: raise IndexError(('Cannot access the variable %s with a ' 'string expression, it is a scalar ' 'variable.') % variable_name) # Add the recorded variable under a known name to the variables # dictionary. Important to deal correctly with # the type of the variable in C++ variables = Variables(None) variables.add_auxiliary_variable('_variable', unit=variable.unit, dtype=variable.dtype, scalar=variable.scalar) variables.add_auxiliary_variable('_cond', unit=Unit(1), dtype=np.bool) abstract_code = '_variable = ' + variable_name + '\n' abstract_code += '_cond = ' + code check_code_units(abstract_code, self, additional_variables=variables, level=level+2, run_namespace=run_namespace) codeobj = create_runner_codeobj(self, abstract_code, 'group_variable_get_conditional', additional_variables=variables, level=level+2, run_namespace=run_namespace, ) return codeobj()
def set_with_expression_conditional(self, varname, variable, cond, code, check_units=True, level=0, run_namespace=None): ''' Sets a variable using a string expression and string condition. Is called by `VariableView.set_item` for statements such as ``S.var['i!=j'] = 'exp(-abs(i-j)/space_constant)*nS'`` Parameters ---------- varname : str The name of the variable to be set. variable : `ArrayVariable` The `ArrayVariable` object for the variable to be set. cond : str The string condition for which the variables should be set. code : str The code that should be executed to set the variable values. check_units : bool, optional Whether to check the units of the expression. level : int, optional How much farther to go up in the stack to find the implicit namespace (if used, see `run_namespace`). run_namespace : dict-like, optional An additional namespace that is used for variable lookup (if not defined, the implicit namespace of local variables is used). ''' if variable.scalar and cond != 'True': raise IndexError(('Cannot conditionally set the scalar variable ' '%s.') % varname) abstract_code_cond = '_cond = '+cond abstract_code = varname + ' = ' + code variables = Variables(None) variables.add_auxiliary_variable('_cond', unit=Unit(1), dtype=np.bool) check_code_units(abstract_code_cond, self, additional_variables=variables, level=level+2, run_namespace=run_namespace) # TODO: Have an additional argument to avoid going through the index # array for situations where iterate_all could be used codeobj = create_runner_codeobj(self, {'condition': abstract_code_cond, 'statement': abstract_code}, 'group_variable_set_conditional', additional_variables=variables, check_units=check_units, level=level+2, run_namespace=run_namespace) codeobj()
def get_with_expression(self, group, variable_name, variable, code, level=0): ''' Gets a variable using a string expression. Is called by `VariableView.get_item` for statements such as ``print G.v['g_syn > 0']``. Parameters ---------- group : `Group` The group providing the context for the indexing. variable_name : str The name of the variable in its context (e.g. ``'g_post'`` for a variable with name ``'g'``) variable : `ArrayVariable` The `ArrayVariable` object for the variable to be set code : str An expression that states a condition for elements that should be selected. Can contain references to indices, such as ``i`` or ``j`` and to state variables. For example: ``'i>3 and v>0*mV'``. level : int, optional How much farther to go up in the stack to find the namespace. ''' # interpret the string expression namespace = get_local_namespace(level+1) additional_namespace = ('implicit-namespace', namespace) # Add the recorded variable under a known name to the variables # dictionary. Important to deal correctly with # the type of the variable in C++ variables = Variables(None) variables.add_auxiliary_variable('_variable', unit=variable.unit, dtype=variable.dtype, scalar=variable.scalar, is_bool=variable.is_bool) variables.add_auxiliary_variable('_cond', unit=Unit(1), dtype=np.bool, is_bool=True) abstract_code = '_variable = ' + variable_name + '\n' abstract_code += '_cond = ' + code check_code_units(abstract_code, group, additional_namespace=additional_namespace, additional_variables=variables) codeobj = create_runner_codeobj(group, abstract_code, 'group_variable_get_conditional', additional_variables=variables, additional_namespace=additional_namespace, ) return codeobj()
def get_with_index_array(self, variable_name, variable, item): if variable.scalar: if not (isinstance(item, slice) and item == slice(None)): raise IndexError(('Illegal index for variable %s, it is a ' 'scalar variable.') % variable_name) indices = np.array(0) else: indices = self.calc_indices(item) # For "normal" variables, we can directly access the underlying data # and use the usual slicing syntax. For subexpressions, however, we # have to evaluate code for the given indices if isinstance(variable, Subexpression): variables = Variables(None) variables.add_auxiliary_variable('_variable', unit=variable.unit, dtype=variable.dtype, scalar=variable.scalar) if indices.shape == (): single_index = True indices = np.array([indices]) else: single_index = False variables.add_array('_group_idx', unit=Unit(1), size=len(indices), dtype=np.int32) variables['_group_idx'].set_value(indices) abstract_code = '_variable = ' + variable_name + '\n' codeobj = create_runner_codeobj(self, abstract_code, 'group_variable_get', additional_variables=variables ) result = codeobj() if single_index and not variable.scalar: return result[0] else: return result else: if variable.scalar: return variable.get_value()[0] else: # We are not going via code generation so we have to take care # of correct indexing (in particular for subgroups) explicitly var_index = self.variables.indices[variable_name] if var_index != '_idx': indices = self.variables[var_index].get_value()[indices] return variable.get_value()[indices]
def set_with_expression_conditional(self, group, varname, variable, cond, code, check_units=True, level=0): ''' Sets a variable using a string expression and string condition. Is called by `VariableView.set_item` for statements such as ``S.var['i!=j'] = 'exp(-abs(i-j)/space_constant)*nS'`` Parameters ---------- group : `Group` The group providing the context for the indexing. varname : str The name of the variable to be set. variable : `ArrayVariable` The `ArrayVariable` object for the variable to be set. cond : str The string condition for which the variables should be set. code : str The code that should be executed to set the variable values. check_units : bool, optional Whether to check the units of the expression. level : int, optional How much farther to go up in the stack to find the namespace. ''' abstract_code_cond = '_cond = '+cond abstract_code = varname + ' = ' + code namespace = get_local_namespace(level + 1) additional_namespace = ('implicit-namespace', namespace) variables = Variables(None) variables.add_auxiliary_variable('_cond', unit=Unit(1), dtype=np.bool, is_bool=True) check_code_units(abstract_code_cond, group, additional_variables=variables, additional_namespace=additional_namespace) # TODO: Have an additional argument to avoid going through the index # array for situations where iterate_all could be used codeobj = create_runner_codeobj(group, {'condition': abstract_code_cond, 'statement': abstract_code}, 'group_variable_set_conditional', additional_variables=variables, additional_namespace=additional_namespace, check_units=check_units) codeobj()
def set_with_expression(self, varname, variable, item, code, check_units=True, level=0, run_namespace=None): ''' Sets a variable using a string expression. Is called by `VariableView.set_item` for statements such as ``S.var[:, :] = 'exp(-abs(i-j)/space_constant)*nS'`` Parameters ---------- varname : str The name of the variable to be set variable : `ArrayVariable` The `ArrayVariable` object for the variable to be set. item : `ndarray` The indices for the variable (in the context of this `group`). code : str The code that should be executed to set the variable values. Can contain references to indices, such as `i` or `j` check_units : bool, optional Whether to check the units of the expression. level : int, optional How much farther to go up in the stack to find the implicit namespace (if used, see `run_namespace`). run_namespace : dict-like, optional An additional namespace that is used for variable lookup (if not defined, the implicit namespace of local variables is used). ''' indices = self.calc_indices(item) abstract_code = varname + ' = ' + code variables = Variables(None) variables.add_array('_group_idx', unit=Unit(1), size=len(indices), dtype=np.int32) variables['_group_idx'].set_value(indices) # TODO: Have an additional argument to avoid going through the index # array for situations where iterate_all could be used codeobj = create_runner_codeobj(self, abstract_code, 'group_variable_set', additional_variables=variables, check_units=check_units, level=level+2, run_namespace=run_namespace) codeobj()
def set_with_expression(self, group, varname, variable, item, code, check_units=True, level=0): ''' Sets a variable using a string expression. Is called by `VariableView.set_item` for statements such as ``S.var[:, :] = 'exp(-abs(i-j)/space_constant)*nS'`` Parameters ---------- group : `Group` The group providing the context for the indexing. varname : str The name of the variable to be set variable : `ArrayVariable` The `ArrayVariable` object for the variable to be set. item : `ndarray` The indices for the variable (in the context of this `group`). code : str The code that should be executed to set the variable values. Can contain references to indices, such as `i` or `j` check_units : bool, optional Whether to check the units of the expression. level : int, optional How much farther to go up in the stack to find the namespace. ''' indices = group.calc_indices(item) abstract_code = varname + ' = ' + code namespace = get_local_namespace(level + 1) additional_namespace = ('implicit-namespace', namespace) variables = Variables(None) variables.add_array('_group_idx', unit=Unit(1), size=len(indices), dtype=np.int32) variables['_group_idx'].set_value(indices) # TODO: Have an additional argument to avoid going through the index # array for situations where iterate_all could be used codeobj = create_runner_codeobj(group, abstract_code, 'group_variable_set', additional_variables=variables, additional_namespace=additional_namespace, check_units=check_units) codeobj()
def __getitem__(self, item): if isinstance(item, basestring): variables = Variables(None) variables.add_auxiliary_variable('_indices', unit=Unit(1), dtype=np.int32) variables.add_auxiliary_variable('_cond', unit=Unit(1), dtype=np.bool) abstract_code = '_cond = ' + item from brian2.devices.device import get_default_codeobject_class codeobj = create_runner_codeobj(self.group, abstract_code, 'group_get_indices', additional_variables=variables, level=1, codeobj_class=get_default_codeobject_class('codegen.string_expression_target') ) return codeobj() else: return self.indices(item)
def before_run(self, namespace): self.update_abstract_code() # If the GroupCodeRunner has variables, add them if hasattr(self, 'variables'): additional_variables = self.variables else: additional_variables = None if self.check_units: check_code_units(self.abstract_code, self.group, additional_variables, namespace) self.codeobj = create_runner_codeobj(group=self.group, code=self.abstract_code, template_name=self.template, name=self.name+'_codeobject*', check_units=self.check_units, additional_variables=additional_variables, additional_namespace=namespace, needed_variables=self.needed_variables, template_kwds=self.template_kwds) self.code_objects[:] = [weakref.proxy(self.codeobj)]
def __getitem__(self, item): if isinstance(item, str): variables = Variables(None) variables.add_auxiliary_variable('_indices', dtype=np.int32) variables.add_auxiliary_variable('_cond', dtype=bool) abstract_code = '_cond = ' + item namespace = get_local_namespace(level=1) from brian2.devices.device import get_device device = get_device() codeobj = create_runner_codeobj(self.group, abstract_code, 'group_get_indices', run_namespace=namespace, additional_variables=variables, codeobj_class=device.code_object_class(fallback_pref='codegen.string_expression_target') ) return codeobj() else: return self.indices(item)
def __getitem__(self, item): if isinstance(item, basestring): variables = Variables(None) variables.add_auxiliary_variable('_indices', dtype=np.int32) variables.add_auxiliary_variable('_cond', dtype=np.bool) abstract_code = '_cond = ' + item namespace = get_local_namespace(level=1) from brian2.devices.device import get_device device = get_device() codeobj = create_runner_codeobj(self.group, abstract_code, 'group_get_indices', run_namespace=namespace, additional_variables=variables, codeobj_class=device.code_object_class(fallback_pref='codegen.string_expression_target') ) return codeobj() else: return self.indices(item)
def __getitem__(self, item): if isinstance(item, basestring): variables = Variables(None) variables.add_auxiliary_variable("_indices", unit=Unit(1), dtype=np.int32) variables.add_auxiliary_variable("_cond", unit=Unit(1), dtype=np.bool) abstract_code = "_cond = " + item check_code_units(abstract_code, self.group, additional_variables=variables, level=1) from brian2.devices.device import get_default_codeobject_class codeobj = create_runner_codeobj( self.group, abstract_code, "group_get_indices", additional_variables=variables, level=1, codeobj_class=get_default_codeobject_class("codegen.string_expression_target"), ) return codeobj() else: return self.indices(item)
def before_run(self, run_namespace=None, level=0): self.update_abstract_code(run_namespace=run_namespace, level=level+1) # If the CodeRunner has variables, add them if hasattr(self, 'variables'): additional_variables = self.variables else: additional_variables = None self.codeobj = create_runner_codeobj(group=self.group, code=self.abstract_code, template_name=self.template, name=self.name+'_codeobject*', check_units=self.check_units, additional_variables=additional_variables, needed_variables=self.needed_variables, run_namespace=run_namespace, level=level+1, template_kwds=self.template_kwds, override_conditional_write=self.override_conditional_write, ) self.code_objects[:] = [weakref.proxy(self.codeobj)]
def __getitem__(self, item): if isinstance(item, basestring): variables = Variables(None) variables.add_auxiliary_variable('_indices', unit=Unit(1), dtype=np.int32) variables.add_auxiliary_variable('_cond', unit=Unit(1), dtype=np.bool) abstract_code = '_cond = ' + item check_code_units(abstract_code, self.group, additional_variables=variables, level=1) codeobj = create_runner_codeobj(self.group, abstract_code, 'group_get_indices', additional_variables=variables, level=1 ) return codeobj() else: return self.group.calc_indices(item)
def get_with_index_array(self, group, variable_name, variable, item): if variable.scalar: if not ((isinstance(item, slice) and item == slice(None)) or item == 0 or (hasattr(item, '__len__') and len(item) == 0)): raise IndexError('Variable is a scalar variable.') indices = np.array([0]) else: indices = group.calc_indices(item) # For "normal" variables, we can directly access the underlying data # and use the usual slicing syntax. For subexpressions, however, we # have to evaluate code for the given indices if isinstance(variable, Subexpression): variables = Variables(None) variables.add_auxiliary_variable('_variable', unit=variable.unit, dtype=variable.dtype, scalar=variable.scalar, is_bool=variable.is_bool) variables.add_array('_group_idx', unit=Unit(1), size=len(indices), dtype=np.int32) variables['_group_idx'].set_value(indices) abstract_code = '_variable = ' + variable_name + '\n' codeobj = create_runner_codeobj(group, abstract_code, 'group_variable_get', additional_variables=variables ) return codeobj() else: # We are not going via code generation so we have to take care # of correct indexing (in particular for subgroups) explicitly var_index = group.variables.indices[variable_name] if var_index != '_idx': indices = group.variables[var_index].get_value()[indices] return variable.get_value()[indices]
def __getitem__(self, item): if isinstance(item, basestring): namespace = get_local_namespace(1) additional_namespace = ('implicit-namespace', namespace) variables = Variables(None) variables.add_auxiliary_variable('_indices', unit=Unit(1), dtype=np.int32) variables.add_auxiliary_variable('_cond', unit=Unit(1), dtype=np.bool, is_bool=True) abstract_code = '_cond = ' + item check_code_units(abstract_code, self.group, additional_namespace=additional_namespace, additional_variables=variables) codeobj = create_runner_codeobj(self.group, abstract_code, 'group_get_indices', additional_variables=variables, additional_namespace=additional_namespace, ) return codeobj() else: return self.group.calc_indices(item)
def _add_synapses(self, sources, targets, n, p, condition=None, level=0): if condition is None: sources = np.atleast_1d(sources).astype(np.int32) targets = np.atleast_1d(targets).astype(np.int32) n = np.atleast_1d(n) p = np.atleast_1d(p) if not len(p) == 1 or p != 1: use_connections = np.random.rand(len(sources)) < p sources = sources[use_connections] targets = targets[use_connections] n = n[use_connections] sources = sources.repeat(n) targets = targets.repeat(n) new_synapses = len(sources) old_N = len(self) new_N = old_N + new_synapses self._resize(new_N) # Deal with subgroups if '_sub_idx' in self.source.variables: real_sources = self.source.variables['_sub_idx'].get_value()[sources] else: real_sources = sources if '_sub_idx' in self.target.variables: real_targets = self.target.variables['_sub_idx'].get_value()[targets] else: real_targets = targets self.variables['_synaptic_pre'].get_value()[old_N:new_N] = real_sources self.variables['_synaptic_post'].get_value()[old_N:new_N] = real_targets else: abstract_code = '_pre_idx = _all_pre \n' abstract_code += '_post_idx = _all_post \n' abstract_code += '_cond = ' + condition + '\n' abstract_code += '_n = ' + str(n) + '\n' abstract_code += '_p = ' + str(p) namespace = get_local_namespace(level + 1) additional_namespace = ('implicit-namespace', namespace) # This overwrites 'i' and 'j' in the synapses' variables dictionary # This is necessary because in the context of synapse creation, i # and j do not correspond to the sources/targets of the existing # synapses but to all the possible sources/targets variables = Variables(None) # Will be set in the template variables.add_auxiliary_variable('i', unit=Unit(1)) variables.add_auxiliary_variable('j', unit=Unit(1)) if '_sub_idx' in self.source.variables: variables.add_reference('_all_pre', self.source.variables['_sub_idx']) else: variables.add_reference('_all_pre', self.source.variables['i']) if '_sub_idx' in self.target.variables: variables.add_reference('_all_post', self.target.variables['_sub_idx']) else: variables.add_reference('_all_post', self.target.variables['i']) variable_indices = defaultdict(lambda: '_idx') for varname in self.variables: if self.variables.indices[varname] == '_presynaptic_idx': variable_indices[varname] = '_all_pre' elif self.variables.indices[varname] == '_postsynaptic_idx': variable_indices[varname] = '_all_post' variable_indices['_all_pre'] = 'i' variable_indices['_all_post'] = 'j' codeobj = create_runner_codeobj(self, abstract_code, 'synapses_create', variable_indices=variable_indices, additional_variables=variables, additional_namespace=additional_namespace, check_units=False ) codeobj()
def _add_synapses(self, sources, targets, n, p, condition=None, namespace=None, level=0): if condition is None: sources = np.atleast_1d(sources).astype(np.int32) targets = np.atleast_1d(targets).astype(np.int32) n = np.atleast_1d(n) p = np.atleast_1d(p) if not len(p) == 1 or p != 1: use_connections = np.random.rand(len(sources)) < p sources = sources[use_connections] targets = targets[use_connections] n = n[use_connections] sources = sources.repeat(n) targets = targets.repeat(n) new_synapses = len(sources) old_N = len(self) new_N = old_N + new_synapses self._resize(new_N) # Deal with subgroups if '_sub_idx' in self.source.variables: real_sources = self.source.variables['_sub_idx'].get_value( )[sources] else: real_sources = sources if '_sub_idx' in self.target.variables: real_targets = self.target.variables['_sub_idx'].get_value( )[targets] else: real_targets = targets self.variables['_synaptic_pre'].get_value( )[old_N:new_N] = real_sources self.variables['_synaptic_post'].get_value( )[old_N:new_N] = real_targets self.variables['N_outgoing'].get_value()[:] += np.bincount( real_sources, minlength=self.variables['N_outgoing'].size) self.variables['N_incoming'].get_value()[:] += np.bincount( real_targets, minlength=self.variables['N_incoming'].size) else: abstract_code = '_pre_idx = _all_pre \n' abstract_code += '_post_idx = _all_post \n' abstract_code += '_cond = ' + condition + '\n' abstract_code += '_n = ' + str(n) + '\n' abstract_code += '_p = ' + str(p) # This overwrites 'i' and 'j' in the synapses' variables dictionary # This is necessary because in the context of synapse creation, i # and j do not correspond to the sources/targets of the existing # synapses but to all the possible sources/targets variables = Variables(None) # Will be set in the template variables.add_auxiliary_variable('_i', unit=Unit(1)) variables.add_auxiliary_variable('_j', unit=Unit(1)) # Make sure that variables have the correct type in the code variables.add_auxiliary_variable('_pre_idx', unit=Unit(1), dtype=np.int32) variables.add_auxiliary_variable('_post_idx', unit=Unit(1), dtype=np.int32) variables.add_auxiliary_variable('_cond', unit=Unit(1), dtype=np.bool) variables.add_auxiliary_variable('_n', unit=Unit(1), dtype=np.int32) variables.add_auxiliary_variable('_p', unit=Unit(1)) if '_sub_idx' in self.source.variables: variables.add_reference('_all_pre', self.source.variables['_sub_idx']) else: variables.add_reference('_all_pre', self.source.variables['i']) if '_sub_idx' in self.target.variables: variables.add_reference('_all_post', self.target.variables['_sub_idx']) else: variables.add_reference('_all_post', self.target.variables['i']) variable_indices = defaultdict(lambda: '_idx') for varname in self.variables: if self.variables.indices[varname] == '_presynaptic_idx': variable_indices[varname] = '_all_pre' elif self.variables.indices[varname] == '_postsynaptic_idx': variable_indices[varname] = '_all_post' variable_indices['_all_pre'] = '_i' variable_indices['_all_post'] = '_j' codeobj = create_runner_codeobj(self, abstract_code, 'synapses_create', variable_indices=variable_indices, additional_variables=variables, check_units=False, run_namespace=namespace, level=level + 1) codeobj()
def _add_synapses(self, sources, targets, n, p, condition=None, namespace=None, level=0): if condition is None: variables = Variables(self) sources = np.atleast_1d(sources).astype(np.int32) targets = np.atleast_1d(targets).astype(np.int32) n = np.atleast_1d(n) p = np.atleast_1d(p) if not len(p) == 1 or p != 1: use_connections = np.random.rand(len(sources)) < p sources = sources[use_connections] targets = targets[use_connections] n = n[use_connections] sources = sources.repeat(n) targets = targets.repeat(n) variables.add_array('sources', Unit(1), len(sources), dtype=np.int32, values=sources) variables.add_array('targets', Unit(1), len(targets), dtype=np.int32, values=targets) # These definitions are important to get the types right in C++ variables.add_auxiliary_variable('_real_sources', Unit(1), dtype=np.int32) variables.add_auxiliary_variable('_real_targets', Unit(1), dtype=np.int32) abstract_code = '' if '_offset' in self.source.variables: variables.add_reference('_source_offset', self.source, '_offset') abstract_code += '_real_sources = sources + _source_offset\n' else: abstract_code += '_real_sources = sources\n' if '_offset' in self.target.variables: variables.add_reference('_target_offset', self.target, '_offset') abstract_code += '_real_targets = targets + _target_offset\n' else: abstract_code += '_real_targets = targets' codeobj = create_runner_codeobj(self, abstract_code, 'synapses_create_array', additional_variables=variables, check_units=False, run_namespace=namespace, level=level+1) codeobj() else: abstract_code = '_pre_idx = _all_pre \n' abstract_code += '_post_idx = _all_post \n' abstract_code += '_cond = ' + condition + '\n' abstract_code += '_n = ' + str(n) + '\n' abstract_code += '_p = ' + str(p) # This overwrites 'i' and 'j' in the synapses' variables dictionary # This is necessary because in the context of synapse creation, i # and j do not correspond to the sources/targets of the existing # synapses but to all the possible sources/targets variables = Variables(None) # Will be set in the template variables.add_auxiliary_variable('_i', unit=Unit(1)) variables.add_auxiliary_variable('_j', unit=Unit(1)) # Make sure that variables have the correct type in the code variables.add_auxiliary_variable('_pre_idx', unit=Unit(1), dtype=np.int32) variables.add_auxiliary_variable('_post_idx', unit=Unit(1), dtype=np.int32) variables.add_auxiliary_variable('_cond', unit=Unit(1), dtype=np.bool) variables.add_auxiliary_variable('_n', unit=Unit(1), dtype=np.int32) variables.add_auxiliary_variable('_p', unit=Unit(1)) if '_sub_idx' in self.source.variables: variables.add_reference('_all_pre', self.source, '_sub_idx') else: variables.add_reference('_all_pre', self.source, 'i') if '_sub_idx' in self.target.variables: variables.add_reference('_all_post', self.target, '_sub_idx') else: variables.add_reference('_all_post', self.target, 'i') variable_indices = defaultdict(lambda: '_idx') for varname in self.variables: if self.variables.indices[varname] == '_presynaptic_idx': variable_indices[varname] = '_all_pre' elif self.variables.indices[varname] == '_postsynaptic_idx': variable_indices[varname] = '_all_post' variable_indices['_all_pre'] = '_i' variable_indices['_all_post'] = '_j' codeobj = create_runner_codeobj(self, abstract_code, 'synapses_create', variable_indices=variable_indices, additional_variables=variables, check_units=False, run_namespace=namespace, level=level+1) codeobj()