def _addDelayExtension(self, numSrcNeurons, max_delay_for_projection, max_delay_per_neuron, original_connector, original_synapse_list, presynaptic_population, postsynaptic_population, label, synapse_dynamics): """ Instantiate new delay extension component, connecting a new edge from the source vertex to it and new edges from it to the target (given by numBlocks). The outgoing edges cover each required block of delays, in groups of MAX_DELAYS_PER_NEURON delay slots (currently 16). """ global controller # If there are any connections with a delay of less than the maximum, # create a direct connection between the two populations only containing # these connections direct_synaptic_sublist = original_synapse_list.create_delay_sublist( 0, max_delay_per_neuron) if (direct_synaptic_sublist.get_max_n_connections() != 0): direct_edge = ProjectionEdge(presynaptic_population.vertex, postsynaptic_population.vertex, controller.dao.machineTimeStep, synapse_list=direct_synaptic_sublist, label=label) controller.add_edge(direct_edge) self.projection_edge = direct_edge # Create a delay extension vertex to do the extra delays self.delay_vertex = presynaptic_population.vertex.delay_vertex if self.delay_vertex is None: sourceName = presynaptic_population.vertex.label delayName = "%s_delayed" % (sourceName) self.delay_vertex = DelayExtension(numSrcNeurons, max_delay_per_neuron, label = delayName) presynaptic_population.vertex.delay_vertex = self.delay_vertex #controller.add_vertex(self.delay_vertex) # Create a connection from the source population to the delay vertex new_label = "%s_to_DE" % (label) remaining_edge = DelayAfferentEdge(presynaptic_population.vertex, self.delay_vertex, label=new_label) controller.add_edge(remaining_edge) # Create a list of the connections with delay larger than that which # can be handled by the neuron itself remaining_synaptic_sublist = original_synapse_list.create_delay_sublist( max_delay_per_neuron, max_delay_for_projection) # Create a special DelayEdge from the delay vertex to the outgoing # population, with the same set of connections delay_label = "DE to %s" % (label) num_blocks = int(math.ceil(float(max_delay_for_projection) / float(max_delay_per_neuron))) - 1 self.delay_edge = DelayProjectionEdge(self.delay_vertex, postsynaptic_population.vertex, controller.dao.machineTimeStep, num_blocks, max_delay_per_neuron, synapse_list = remaining_synaptic_sublist, synapse_dynamics=synapse_dynamics, label=delay_label) controller.add_edge(self.delay_edge)
def _addDelayExtension(self, numSrcNeurons, max_delay_for_projection, max_delay_per_neuron, original_connector, original_synapse_list, presynaptic_population, postsynaptic_population, label, synapse_dynamics): """ Instantiate new delay extension component, connecting a new edge from the source vertex to it and new edges from it to the target (given by numBlocks). The outgoing edges cover each required block of delays, in groups of MAX_DELAYS_PER_NEURON delay slots (currently 16). """ global controller # If there are any connections with a delay of less than the maximum, # create a direct connection between the two populations only containing # these connections direct_synaptic_sublist = original_synapse_list.create_delay_sublist( 0, max_delay_per_neuron) if (direct_synaptic_sublist.get_max_n_connections() != 0): direct_edge = ProjectionEdge(presynaptic_population.vertex, postsynaptic_population.vertex, controller.dao.machineTimeStep, synapse_list=direct_synaptic_sublist, label=label) controller.add_edge(direct_edge) self.projection_edge = direct_edge # Create a delay extension vertex to do the extra delays self.delay_vertex = presynaptic_population.vertex.delay_vertex if self.delay_vertex is None: sourceName = presynaptic_population.vertex.label delayName = "%s_delayed" % (sourceName) self.delay_vertex = DelayExtension(numSrcNeurons, max_delay_per_neuron, label=delayName) presynaptic_population.vertex.delay_vertex = self.delay_vertex #controller.add_vertex(self.delay_vertex) # Create a connection from the source population to the delay vertex new_label = "%s_to_DE" % (label) remaining_edge = DelayAfferentEdge(presynaptic_population.vertex, self.delay_vertex, label=new_label) controller.add_edge(remaining_edge) # Create a list of the connections with delay larger than that which # can be handled by the neuron itself remaining_synaptic_sublist = original_synapse_list.create_delay_sublist( max_delay_per_neuron, max_delay_for_projection) # Create a special DelayEdge from the delay vertex to the outgoing # population, with the same set of connections delay_label = "DE to %s" % (label) num_blocks = int( math.ceil( float(max_delay_for_projection) / float(max_delay_per_neuron))) - 1 self.delay_edge = DelayProjectionEdge( self.delay_vertex, postsynaptic_population.vertex, controller.dao.machineTimeStep, num_blocks, max_delay_per_neuron, synapse_list=remaining_synaptic_sublist, synapse_dynamics=synapse_dynamics, label=delay_label) controller.add_edge(self.delay_edge)
class Projection(object): """ A container for all the connections of a given type (same synapse type and plasticity mechanisms) between two populations, together with methods to set parameters of those connections, including of plasticity mechanisms. :param `pacman103.front.pynn.Population` presynaptic_population: presynaptic Population for the Projection :param `pacman103.front.pynn.Population` postsynaptic_population: postsynaptic Population for the Projection :param `pacman103.front.pynn.connectors` method: an instance of the connection method and parameters for the Projection """ def __init__(self, presynaptic_population, postsynaptic_population, connector, source=None, target='excitatory', synapse_dynamics=None, label=None, rng=None): """ Instantiates a :py:object:`Projection`. """ global controller self.projection_edge = None if issubclass(type(postsynaptic_population.vertex), PopulationVertex): # Check that the "target" is an acceptable value targets = postsynaptic_population.vertex.get_synapse_targets() if not target in targets: raise exceptions.PacmanException( "Target {} is not available in " + "the post-synaptic population (choices are {})".format( target, targets)) synapse_type = postsynaptic_population.vertex.get_synapse_id( target) else: raise exceptions.ConfigurationException( "postsynaptic_population is " "not a supposal reciever of" " synaptic projections") # Check that the edge doesn't already exist elsewhere # This would be a possible place for a merge at some point, # but this needs more thought for edge in controller.dao.get_edges(): if (edge.prevertex == presynaptic_population.vertex and edge.postvertex == postsynaptic_population.vertex): raise exceptions.PacmanException( "More than one connection between the same pair of" + " vertices is not currently supported") synapse_list = connector.generate_synapse_list( presynaptic_population.vertex, postsynaptic_population.vertex, 1000.0 / controller.dao.machineTimeStep, synapse_type) self.read_synapse_list = None # If there are some negative weights if synapse_list.get_min_weight() < 0: # If there are mixed negative and positive weights, # raise an exception if synapse_list.get_max_weight() > 0: raise exceptions.PacmanException("Weights must be positive") # Otherwise, the weights are all negative, so invert them(!) else: synapse_list.flip() # check if all delays requested can fit into the natively supported # delays in the models min_delay, max_delay = synapse_list.get_min_max_delay() natively_supported_delay_for_models = MAX_SUPPORTED_DELAY_TICS delay_extention_max_supported_delay = \ MAX_DELAY_BLOCKS * MAX_TIMER_TICS_SUPPORTED_PER_BLOCK if max_delay > (natively_supported_delay_for_models + delay_extention_max_supported_delay): raise exceptions.ConfigurationException( "the max delay for projection {} is not " "supported by the pacman " "toolchain".format(max_delay)) if conf.config.has_option("Model", "max_delay"): user_max_delay = conf.config.get("Model", "max_delay") if max_delay > user_max_delay: logger.warn( "The end user entered a max delay to which the projection breaks" ) if (max_delay > natively_supported_delay_for_models): source_sz = presynaptic_population.vertex.atoms self._addDelayExtension(source_sz, max_delay, natively_supported_delay_for_models, connector, synapse_list, presynaptic_population, postsynaptic_population, label, synapse_dynamics) else: self.projection_edge = ProjectionEdge( presynaptic_population.vertex, postsynaptic_population.vertex, controller.dao.machineTimeStep, synapse_list=synapse_list, synapse_dynamics=synapse_dynamics, label=label) self.delay_edge = None controller.add_edge(self.projection_edge) def _addDelayExtension(self, numSrcNeurons, max_delay_for_projection, max_delay_per_neuron, original_connector, original_synapse_list, presynaptic_population, postsynaptic_population, label, synapse_dynamics): """ Instantiate new delay extension component, connecting a new edge from the source vertex to it and new edges from it to the target (given by numBlocks). The outgoing edges cover each required block of delays, in groups of MAX_DELAYS_PER_NEURON delay slots (currently 16). """ global controller # If there are any connections with a delay of less than the maximum, # create a direct connection between the two populations only containing # these connections direct_synaptic_sublist = original_synapse_list.create_delay_sublist( 0, max_delay_per_neuron) if (direct_synaptic_sublist.get_max_n_connections() != 0): direct_edge = ProjectionEdge(presynaptic_population.vertex, postsynaptic_population.vertex, controller.dao.machineTimeStep, synapse_list=direct_synaptic_sublist, label=label) controller.add_edge(direct_edge) self.projection_edge = direct_edge # Create a delay extension vertex to do the extra delays self.delay_vertex = presynaptic_population.vertex.delay_vertex if self.delay_vertex is None: sourceName = presynaptic_population.vertex.label delayName = "%s_delayed" % (sourceName) self.delay_vertex = DelayExtension(numSrcNeurons, max_delay_per_neuron, label=delayName) presynaptic_population.vertex.delay_vertex = self.delay_vertex #controller.add_vertex(self.delay_vertex) # Create a connection from the source population to the delay vertex new_label = "%s_to_DE" % (label) remaining_edge = DelayAfferentEdge(presynaptic_population.vertex, self.delay_vertex, label=new_label) controller.add_edge(remaining_edge) # Create a list of the connections with delay larger than that which # can be handled by the neuron itself remaining_synaptic_sublist = original_synapse_list.create_delay_sublist( max_delay_per_neuron, max_delay_for_projection) # Create a special DelayEdge from the delay vertex to the outgoing # population, with the same set of connections delay_label = "DE to %s" % (label) num_blocks = int( math.ceil( float(max_delay_for_projection) / float(max_delay_per_neuron))) - 1 self.delay_edge = DelayProjectionEdge( self.delay_vertex, postsynaptic_population.vertex, controller.dao.machineTimeStep, num_blocks, max_delay_per_neuron, synapse_list=remaining_synaptic_sublist, synapse_dynamics=synapse_dynamics, label=delay_label) controller.add_edge(self.delay_edge) def describe(self, template='projection_default.txt', engine='default'): """ Returns a human-readable description of the projection. The output may be customized by specifying a different template togther with an associated template engine (see ``pyNN.descriptions``). If template is None, then a dictionary containing the template context will be returned. """ raise NotImplementedError def __getitem__(self, i): """Return the `i`th connection within the Projection.""" raise NotImplementedError def _get_synaptic_data(self): if self.read_synapse_list is None: global controller synapse_list = None delay_synapse_list = None if self.projection_edge is not None: synapse_list = self.projection_edge.get_synaptic_data( controller, MAX_SUPPORTED_DELAY_TICS) if self.delay_edge is not None: delay_synapse_list = self.delay_edge.get_synaptic_data( controller, MAX_SUPPORTED_DELAY_TICS) # If there is both a delay and a non-delay list, merge them if synapse_list is not None and delay_synapse_list is not None: rows = synapse_list.get_rows() delay_rows = delay_synapse_list.get_rows() for i in range(len(rows)): rows[i].append(delay_rows[i]) self.read_synapse_list = synapse_list # If there is only a synapse list, return that elif synapse_list is not None: self.read_synapse_list = synapse_list # Otherwise return the delay list (there should be at least one!) else: self.read_synapse_list = delay_synapse_list return self.read_synapse_list def getDelays(self, format='list', gather=True): """ Get synaptic delays for all connections in this Projection. Possible formats are: a list of length equal to the number of connections in the projection, a 2D delay array (with NaN for non-existent connections). """ global controller timer = None if conf.config.getboolean("Reports", "outputTimesForSections"): timer = Timer() timer.start_timing() synapse_list = self._get_synaptic_data() if conf.config.getboolean("Reports", "outputTimesForSections"): timer.take_sample() if format == 'list': delays = list() for row in synapse_list.get_rows(): delays.extend(row.delays * (float(controller.dao.machineTimeStep) / 1000.0)) return delays delays = numpy.zeros((self.projection_edge.prevertex.atoms, self.projection_edge.postvertex.atoms)) rows = synapse_list.get_rows() for pre_atom in range(len(rows)): row = rows[pre_atom] for i in len(row.target_indices): post_atom = row.target_indices[i] delay = (float(row.delays[i]) * (float(controller.dao.machineTimeStep) / 1000.0)) delays[pre_atom][post_atom] = delay return delays def getSynapseDynamics(self, parameter_name, format='list', gather=True): """ Get parameters of the dynamic synapses for all connections in this Projection. """ raise NotImplementedError def getWeights(self, format='list'): """ Get synaptic weights for all connections in this Projection. (pyNN gather parameter not supported from the signiture getWeights(self, format='list', gather=True):) Possible formats are: a list of length equal to the number of connections in the projection, a 2D weight array (with NaN for non-existent connections). Note that for the array format, if there is more than one connection between two cells, the summed weight will be given. """ timer = None if conf.config.getboolean("Reports", "outputTimesForSections"): timer = Timer() timer.start_timing() synapse_list = self._get_synaptic_data() if conf.config.getboolean("Reports", "outputTimesForSections"): timer.take_sample() if format == 'list': weights = list() for row in synapse_list.get_rows(): weights.extend(row.weights) return weights elif format == 'array': weights = numpy.zeros((self.projection_edge.prevertex.atoms, self.projection_edge.postvertex.atoms)) rows = synapse_list.get_rows() for pre_atom, row in enumerate(rows): for post_atom, weight in zip(row.target_indices, row.weights): weights[pre_atom][post_atom] = weight return weights def __len__(self): """Return the total number of local connections.""" raise NotImplementedError def printDelays(self, file, format='list', gather=True): """ Print synaptic weights to file. In the array format, zeros are printed for non-existent connections. """ raise NotImplementedError def printWeights(self, file, format='list', gather=True): """ Print synaptic weights to file. In the array format, zeros are printed for non-existent connections. """ raise NotImplementedError def randomizeWeights(self, rand_distr): """ Set weights to random values taken from rand_distr. """ raise NotImplementedError def randomizeDelays(self, rand_distr): """ Set delays to random values taken from rand_distr. """ raise NotImplementedError def randomizeSynapseDynamics(self, param, rand_distr): """ Set parameters of the synapse dynamics to values taken from rand_distr """ raise NotImplementedError def __repr__(self): ''' returns a string rep of the projection ''' return "prjection {}".format(self.projection_edge.label) def saveConnections(self, file, gather=True, compatible_output=True): """ Save connections to file in a format suitable for reading in with a FromFileConnector. """ raise NotImplementedError def size(self, gather=True): """ Return the total number of connections. - only local connections, if gather is False, - all connections, if gather is True (default) """ raise NotImplementedError def setDelays(self, d): """ d can be a single number, in which case all delays are set to this value, or a list/1D array of length equal to the number of connections in the projection, or a 2D array with the same dimensions as the connectivity matrix (as returned by `getDelays(format='array')`). """ raise NotImplementedError def setSynapseDynamics(self, param, value): """ Set parameters of the dynamic synapses for all connections in this projection. """ raise NotImplementedError def setWeights(self, w): """ w can be a single number, in which case all weights are set to this value, or a list/1D array of length equal to the number of connections in the projection, or a 2D array with the same dimensions as the connectivity matrix (as returned by `getWeights(format='array')`). Weights should be in nA for current-based and uS for conductance-based synapses. """ raise NotImplementedError def weightHistogram(self, min=None, max=None, nbins=10): """ Return a histogram of synaptic weights. If min and max are not given, the minimum and maximum weights are calculated automatically. """ raise NotImplementedError
class Projection(object): """ A container for all the connections of a given type (same synapse type and plasticity mechanisms) between two populations, together with methods to set parameters of those connections, including of plasticity mechanisms. :param `pacman103.front.pynn.Population` presynaptic_population: presynaptic Population for the Projection :param `pacman103.front.pynn.Population` postsynaptic_population: postsynaptic Population for the Projection :param `pacman103.front.pynn.connectors` method: an instance of the connection method and parameters for the Projection """ def __init__( self, presynaptic_population, postsynaptic_population, connector, source=None, target='excitatory', synapse_dynamics=None, label=None, rng=None): """ Instantiates a :py:object:`Projection`. """ global controller self.projection_edge = None if issubclass(type(postsynaptic_population.vertex), PopulationVertex): # Check that the "target" is an acceptable value targets = postsynaptic_population.vertex.get_synapse_targets() if not target in targets: raise exceptions.PacmanException("Target {} is not available in " + "the post-synaptic population (choices are {})".format( target, targets)) synapse_type = postsynaptic_population.vertex.get_synapse_id(target) else: raise exceptions.ConfigurationException("postsynaptic_population is " "not a supposal reciever of" " synaptic projections") # Check that the edge doesn't already exist elsewhere # This would be a possible place for a merge at some point, # but this needs more thought for edge in controller.dao.get_edges(): if (edge.prevertex == presynaptic_population.vertex and edge.postvertex == postsynaptic_population.vertex): raise exceptions.PacmanException( "More than one connection between the same pair of" + " vertices is not currently supported") synapse_list = connector.generate_synapse_list( presynaptic_population.vertex, postsynaptic_population.vertex, 1000.0 / controller.dao.machineTimeStep, synapse_type) self.read_synapse_list = None # If there are some negative weights if synapse_list.get_min_weight() < 0: # If there are mixed negative and positive weights, # raise an exception if synapse_list.get_max_weight() > 0: raise exceptions.PacmanException("Weights must be positive") # Otherwise, the weights are all negative, so invert them(!) else: synapse_list.flip() # check if all delays requested can fit into the natively supported # delays in the models min_delay, max_delay = synapse_list.get_min_max_delay() natively_supported_delay_for_models = MAX_SUPPORTED_DELAY_TICS delay_extention_max_supported_delay = \ MAX_DELAY_BLOCKS * MAX_TIMER_TICS_SUPPORTED_PER_BLOCK if max_delay > (natively_supported_delay_for_models + delay_extention_max_supported_delay): raise exceptions.ConfigurationException("the max delay for projection {} is not " "supported by the pacman " "toolchain".format(max_delay)) if conf.config.has_option("Model", "max_delay"): user_max_delay = conf.config.get("Model", "max_delay") if max_delay > user_max_delay: logger.warn("The end user entered a max delay to which the projection breaks") if (max_delay > natively_supported_delay_for_models): source_sz = presynaptic_population.vertex.atoms self._addDelayExtension(source_sz, max_delay, natively_supported_delay_for_models, connector, synapse_list, presynaptic_population, postsynaptic_population, label, synapse_dynamics) else: self.projection_edge = ProjectionEdge(presynaptic_population.vertex, postsynaptic_population.vertex, controller.dao.machineTimeStep, synapse_list=synapse_list, synapse_dynamics=synapse_dynamics, label=label) self.delay_edge = None controller.add_edge(self.projection_edge) def _addDelayExtension(self, numSrcNeurons, max_delay_for_projection, max_delay_per_neuron, original_connector, original_synapse_list, presynaptic_population, postsynaptic_population, label, synapse_dynamics): """ Instantiate new delay extension component, connecting a new edge from the source vertex to it and new edges from it to the target (given by numBlocks). The outgoing edges cover each required block of delays, in groups of MAX_DELAYS_PER_NEURON delay slots (currently 16). """ global controller # If there are any connections with a delay of less than the maximum, # create a direct connection between the two populations only containing # these connections direct_synaptic_sublist = original_synapse_list.create_delay_sublist( 0, max_delay_per_neuron) if (direct_synaptic_sublist.get_max_n_connections() != 0): direct_edge = ProjectionEdge(presynaptic_population.vertex, postsynaptic_population.vertex, controller.dao.machineTimeStep, synapse_list=direct_synaptic_sublist, label=label) controller.add_edge(direct_edge) self.projection_edge = direct_edge # Create a delay extension vertex to do the extra delays self.delay_vertex = presynaptic_population.vertex.delay_vertex if self.delay_vertex is None: sourceName = presynaptic_population.vertex.label delayName = "%s_delayed" % (sourceName) self.delay_vertex = DelayExtension(numSrcNeurons, max_delay_per_neuron, label = delayName) presynaptic_population.vertex.delay_vertex = self.delay_vertex #controller.add_vertex(self.delay_vertex) # Create a connection from the source population to the delay vertex new_label = "%s_to_DE" % (label) remaining_edge = DelayAfferentEdge(presynaptic_population.vertex, self.delay_vertex, label=new_label) controller.add_edge(remaining_edge) # Create a list of the connections with delay larger than that which # can be handled by the neuron itself remaining_synaptic_sublist = original_synapse_list.create_delay_sublist( max_delay_per_neuron, max_delay_for_projection) # Create a special DelayEdge from the delay vertex to the outgoing # population, with the same set of connections delay_label = "DE to %s" % (label) num_blocks = int(math.ceil(float(max_delay_for_projection) / float(max_delay_per_neuron))) - 1 self.delay_edge = DelayProjectionEdge(self.delay_vertex, postsynaptic_population.vertex, controller.dao.machineTimeStep, num_blocks, max_delay_per_neuron, synapse_list = remaining_synaptic_sublist, synapse_dynamics=synapse_dynamics, label=delay_label) controller.add_edge(self.delay_edge) def describe(self, template='projection_default.txt', engine='default'): """ Returns a human-readable description of the projection. The output may be customized by specifying a different template togther with an associated template engine (see ``pyNN.descriptions``). If template is None, then a dictionary containing the template context will be returned. """ raise NotImplementedError def __getitem__(self, i): """Return the `i`th connection within the Projection.""" raise NotImplementedError def _get_synaptic_data(self): if self.read_synapse_list is None: global controller synapse_list = None delay_synapse_list = None if self.projection_edge is not None: synapse_list = self.projection_edge.get_synaptic_data( controller, MAX_SUPPORTED_DELAY_TICS) if self.delay_edge is not None: delay_synapse_list = self.delay_edge.get_synaptic_data( controller, MAX_SUPPORTED_DELAY_TICS) # If there is both a delay and a non-delay list, merge them if synapse_list is not None and delay_synapse_list is not None: rows = synapse_list.get_rows() delay_rows = delay_synapse_list.get_rows() for i in range(len(rows)): rows[i].append(delay_rows[i]) self.read_synapse_list = synapse_list # If there is only a synapse list, return that elif synapse_list is not None: self.read_synapse_list = synapse_list # Otherwise return the delay list (there should be at least one!) else: self.read_synapse_list = delay_synapse_list return self.read_synapse_list def getDelays(self, format='list', gather=True): """ Get synaptic delays for all connections in this Projection. Possible formats are: a list of length equal to the number of connections in the projection, a 2D delay array (with NaN for non-existent connections). """ global controller timer = None if conf.config.getboolean("Reports", "outputTimesForSections"): timer = Timer() timer.start_timing() synapse_list = self._get_synaptic_data() if conf.config.getboolean("Reports", "outputTimesForSections"): timer.take_sample() if format == 'list': delays = list() for row in synapse_list.get_rows(): delays.extend(row.delays * (float(controller.dao.machineTimeStep) / 1000.0)) return delays delays = numpy.zeros((self.projection_edge.prevertex.atoms, self.projection_edge.postvertex.atoms)) rows = synapse_list.get_rows() for pre_atom in range(len(rows)): row = rows[pre_atom] for i in len(row.target_indices): post_atom = row.target_indices[i] delay = (float(row.delays[i]) * (float(controller.dao.machineTimeStep) / 1000.0)) delays[pre_atom][post_atom] = delay return delays def getSynapseDynamics(self, parameter_name, format='list', gather=True): """ Get parameters of the dynamic synapses for all connections in this Projection. """ raise NotImplementedError def getWeights(self, format='list'): """ Get synaptic weights for all connections in this Projection. (pyNN gather parameter not supported from the signiture getWeights(self, format='list', gather=True):) Possible formats are: a list of length equal to the number of connections in the projection, a 2D weight array (with NaN for non-existent connections). Note that for the array format, if there is more than one connection between two cells, the summed weight will be given. """ timer = None if conf.config.getboolean("Reports", "outputTimesForSections"): timer = Timer() timer.start_timing() synapse_list = self._get_synaptic_data() if conf.config.getboolean("Reports", "outputTimesForSections"): timer.take_sample() if format == 'list': weights = list() for row in synapse_list.get_rows(): weights.extend(row.weights) return weights elif format == 'array': weights = numpy.zeros((self.projection_edge.prevertex.atoms, self.projection_edge.postvertex.atoms)) rows = synapse_list.get_rows() for pre_atom, row in enumerate(rows): for post_atom, weight in zip(row.target_indices, row.weights): weights[pre_atom][post_atom] = weight return weights def __len__(self): """Return the total number of local connections.""" raise NotImplementedError def printDelays(self, file, format='list', gather=True): """ Print synaptic weights to file. In the array format, zeros are printed for non-existent connections. """ raise NotImplementedError def printWeights(self, file, format='list', gather=True): """ Print synaptic weights to file. In the array format, zeros are printed for non-existent connections. """ raise NotImplementedError def randomizeWeights(self, rand_distr): """ Set weights to random values taken from rand_distr. """ raise NotImplementedError def randomizeDelays(self, rand_distr): """ Set delays to random values taken from rand_distr. """ raise NotImplementedError def randomizeSynapseDynamics(self, param, rand_distr): """ Set parameters of the synapse dynamics to values taken from rand_distr """ raise NotImplementedError def __repr__(self): ''' returns a string rep of the projection ''' return "prjection {}".format(self.projection_edge.label) def saveConnections(self, file, gather=True, compatible_output=True): """ Save connections to file in a format suitable for reading in with a FromFileConnector. """ raise NotImplementedError def size(self, gather=True): """ Return the total number of connections. - only local connections, if gather is False, - all connections, if gather is True (default) """ raise NotImplementedError def setDelays(self, d): """ d can be a single number, in which case all delays are set to this value, or a list/1D array of length equal to the number of connections in the projection, or a 2D array with the same dimensions as the connectivity matrix (as returned by `getDelays(format='array')`). """ raise NotImplementedError def setSynapseDynamics(self, param, value): """ Set parameters of the dynamic synapses for all connections in this projection. """ raise NotImplementedError def setWeights(self, w): """ w can be a single number, in which case all weights are set to this value, or a list/1D array of length equal to the number of connections in the projection, or a 2D array with the same dimensions as the connectivity matrix (as returned by `getWeights(format='array')`). Weights should be in nA for current-based and uS for conductance-based synapses. """ raise NotImplementedError def weightHistogram(self, min=None, max=None, nbins=10): """ Return a histogram of synaptic weights. If min and max are not given, the minimum and maximum weights are calculated automatically. """ raise NotImplementedError