Example #1
0
    def set(self, name, value):
        """
        Set connection attributes for all connections on the local MPI node.
        
        `name`  -- attribute name
        `value` -- the attribute numeric value, or a list/1D array of such
                   values of the same length as the number of local connections,
                   or a 2D array with the same dimensions as the connectivity
                   matrix (as returned by `get(format='array')`).
        """
        if not (common.is_number(value) or common.is_listlike(value)):
            raise TypeError(
                "Argument should be a numeric type (int, float...), a list, or a numpy array."
            )

        if isinstance(value, numpy.ndarray) and len(value.shape) == 2:
            offset = (self.parent.pre.first_id, self.parent.post.first_id)
            value_list = []
            connection_parameters = nest.GetStatus(self.connections)
            for conn in connection_parameters:
                addr = (conn['source'] - offset[0], conn['target'] - offset[1])
                try:
                    val = value[addr]
                except IndexError, e:
                    raise IndexError("%s. addr=%s" % (e, addr))
                if numpy.isnan(val):
                    raise Exception(
                        "Array contains no value for synapse from %d to %d" %
                        (c.source, c.target))
                else:
                    value_list.append(val)
            value = value_list
Example #2
0
 def _set_spiketimes(self, spiketimes):
     assert common.is_listlike(spiketimes)
     if len(spiketimes) == 0 or common.is_number(spiketimes[0]):
         spiketimes = [spiketimes for i in xrange(len(self))]
     assert len(spiketimes) == len(
         self
     ), "spiketimes (length %d) must contain as many iterables as there are cells in the group (%d)." % (
         len(spiketimes), len(self))
     self._threshold.set_spike_times(spiketimes)
Example #3
0
    def connect(self, source, targets, weights, delays):
        """
        Connect a neuron to one or more other neurons.
        
        `source`  -- the ID of the pre-synaptic cell.
        `targets` -- a list/1D array of post-synaptic cell IDs, or a single ID.
        `weight`  -- a list/1D array of connection weights, or a single weight.
                     Must have the same length as `targets`.
        `delays`  -- a list/1D array of connection delays, or a single delay.
                     Must have the same length as `targets`.
        """
        # are we sure the targets are all on the current node?
        if common.is_listlike(source):
            assert len(source) == 1
            source = source[0]
        if not common.is_listlike(targets):
            targets = [targets]
        assert len(targets) > 0
        if self.synapse_type not in ('excitatory', 'inhibitory', None):
            raise common.ConnectionError(
                "synapse_type must be 'excitatory', 'inhibitory', or None (equivalent to 'excitatory')"
            )
        weights = weights * 1000.0  # weights should be in nA or uS, but iaf_neuron uses pA and iaf_cond_neuron uses nS.
        # Using convention in this way is not ideal. We should
        # be able to look up the units used by each model somewhere.
        if self.synapse_type == 'inhibitory' and common.is_conductance(
                targets[0]):
            weights = -1 * weights  # NEST wants negative values for inhibitory weights, even if these are conductances
        if isinstance(weights, numpy.ndarray):
            weights = weights.tolist()
        elif isinstance(weights, float):
            weights = [weights]
        if isinstance(delays, numpy.ndarray):
            delays = delays.tolist()
        elif isinstance(delays, float):
            delays = [delays]

        try:
            nest.DivergentConnect([source], targets, weights, delays,
                                  self.synapse_model)
        except nest.NESTError, e:
            raise common.ConnectionError(
                "%s. source=%s, targets=%s, weights=%s, delays=%s, synapse model='%s'"
                % (e, source, targets, weights, delays, self.synapse_model))
Example #4
0
    def _probabilistic_connect(self, projection, p):
        """
        Connect-up a Projection with connection probability p, where p may be either
        a float 0<=p<=1, or a dict containing a float array for each pre-synaptic
        cell, the array containing the connection probabilities for all the local
        targets of that pre-synaptic cell.
        """
        if isinstance(projection.rng, random.NativeRNG):
            raise Exception("Use of NativeRNG not implemented.")
        else:
            rng = projection.rng

        local = projection.post._mask_local.flatten()
        is_conductance = common.is_conductance(projection.post.index(0))
        for src in projection.pre.all():
            # ( the following two lines are a nice idea, but this needs some thought for
            #   the parallel case, to ensure reproducibility when varying the number
            #   of processors
            #      N = rng.binomial(npost,self.p_connect,1)[0]
            #      targets = sample(postsynaptic_neurons, N)   # )
            N = projection.post.size
            # if running in parallel, rng.next(N) will not return N values, but only
            # as many as are needed on this node, as determined by mask_local.
            # Over the simulation as a whole (all nodes), N values will indeed be
            # returned.
            rarr = rng.next(N, 'uniform', (0, 1), mask_local=local)
            if not common.is_listlike(rarr) and common.is_number(
                    rarr):  # if N=1, rarr will be a single number
                rarr = numpy.array([rarr])
            if common.is_number(p):
                create = rarr < p
            else:
                create = rarr < p[src][local]
            if create.shape != projection.post.local_cells.shape:
                logger.warning(
                    "Too many random numbers. Discarding the excess. Did you specify MPI rank and number of processes when you created the random number generator?"
                )
                create = create[:projection.post.local_cells.size]
            targets = projection.post.local_cells[create].tolist()

            weights = self.get_weights(N, local)[create]
            weights = common.check_weight(weights, projection.synapse_type,
                                          is_conductance)
            delays = self.get_delays(N, local)[create]

            if not self.allow_self_connections and projection.pre == projection.post and src in targets:
                assert len(targets) == len(weights) == len(delays)
                i = targets.index(src)
                weights = numpy.delete(weights, i)
                delays = numpy.delete(delays, i)
                targets.remove(src)

            if len(targets) > 0:
                projection.connection_manager.connect(src, targets, weights,
                                                      delays)
Example #5
0
    def connect(self, source, targets, weights, delays):
        """
        Connect a neuron to one or more other neurons with a static connection.
        
        `source`  -- the ID of the pre-synaptic cell.
        `targets` -- a list/1D array of post-synaptic cell IDs, or a single ID.
        `weight`  -- a list/1D array of connection weights, or a single weight.
                     Must have the same length as `targets`.
        `delays`  -- a list/1D array of connection delays, or a single delay.
                     Must have the same length as `targets`.
        """
        if not isinstance(source, (int, long)) or source < 0:
            errmsg = "Invalid source ID: %s" % source
            raise common.ConnectionError(errmsg)
        if not common.is_listlike(targets):
            targets = [targets]
        if isinstance(weights, float):
            weights = [weights]
        if isinstance(delays, float):
            delays = [delays]
        assert len(targets) > 0
        for target in targets:
            if not isinstance(target, common.IDMixin):
                raise common.ConnectionError("Invalid target ID: %s" % target)
        assert len(targets) == len(weights) == len(delays), "%s %s %s" % (
            len(targets), len(weights), len(delays))
        if common.is_conductance(targets[0]):
            weight_scale_factor = 1e-6  # Convert from µS to S
        else:
            weight_scale_factor = 1e-9  # Convert from nA to A

        synapse_type = self.synapse_type or "excitatory"
        if isinstance(synapse_type, basestring):
            syn_target_id = ConnectionManager.synapse_target_ids[synapse_type]
            syn_factory = pypcsim.SimpleScalingSpikingSynapse(
                syn_target_id, weights[0], delays[0])
        elif isinstance(synapse_type, pypcsim.SimObject):
            syn_factory = synapse_type
        else:
            raise common.ConnectionError(
                "synapse_type must be a string or a PCSIM synapse factory. Actual type is %s"
                % type(synapse_type))
        for target, weight, delay in zip(targets, weights, delays):
            syn_factory.W = weight * weight_scale_factor
            syn_factory.delay = delay * 0.001  # ms --> s
            try:
                c = net.connect(source, target, syn_factory)
            except RuntimeError, e:
                raise common.ConnectionError(e)
            if target.local:
                self.connections.append(
                    Connection(source, target, net.object(c),
                               1.0 / weight_scale_factor))
Example #6
0
 def set(self, name, value):
     """
     Set connection attributes for all connections in this manager.
     
     `name`  -- attribute name
     `value` -- the attribute numeric value, or a list/1D array of such
                values of the same length as the number of local connections,
                or a 2D array with the same dimensions as the connectivity
                matrix (as returned by `get(format='array')`).
     """
     if self.parent is None:
         raise Exception(
             "Only implemented for connections created via a Projection object, not using connect()"
         )
     synapse_obj = self.parent.post.celltype.synapses[self.parent.target
                                                      or "excitatory"]
     weight_units = ("cond" in self.parent.post.celltype.__class__.__name__
                     ) and uS or nA
     ###print "in ConnectionManager.set(), weight_units = %s" % weight_units
     bc = self._get_brian_connection(self.parent.pre.brian_cells,
                                     self.parent.post.brian_cells,
                                     synapse_obj, weight_units)
     if name == 'weight':
         M = bc.W
         units = weight_units
     elif name == 'delay':
         M = bc.delay
         units = ms
     else:
         raise Exception(
             "Setting parameters other than weight and delay not yet supported."
         )
     if common.is_number(value):
         for row in M.data:
             for i in range(len(row)):
                 row[i] = value * units
     elif isinstance(value, numpy.ndarray) and len(value.shape) == 2:
         address_gen = ((i, j) for i, row in enumerate(bc.W.rows)
                        for j in row)
         for (i, j) in address_gen:
             M[i, j] = value[i, j] * units
     elif common.is_listlike(value):
         assert len(value) == M.getnnz()
         address_gen = ((i, j) for i, row in enumerate(bc.W.rows)
                        for j in row)
         for ((i, j), val) in izip(address_gen, value):
             M[i, j] = val * units
     else:
         raise Exception("Values must be scalars or lists/arrays")
Example #7
0
    def connect(self, source, targets, weights, delays):
        """
        Connect a neuron to one or more other neurons with a static connection.
        
        `source`  -- the ID of the pre-synaptic cell.
        `targets` -- a list/1D array of post-synaptic cell IDs, or a single ID.
        `weight`  -- a list/1D array of connection weights, or a single weight.
                     Must have the same length as `targets`.
        `delays`  -- a list/1D array of connection delays, or a single delay.
                     Must have the same length as `targets`.
        """
        if not isinstance(source,
                          int) or source > state.gid_counter or source < 0:
            errmsg = "Invalid source ID: %s (gid_counter=%d)" % (
                source, state.gid_counter)
            raise common.ConnectionError(errmsg)
        if not common.is_listlike(targets):
            targets = [targets]
        if isinstance(weights, float):
            weights = [weights]
        if isinstance(delays, float):
            delays = [delays]
        assert len(targets) > 0
        for target in targets:
            if not isinstance(target, common.IDMixin):
                raise common.ConnectionError("Invalid target ID: %s" % target)

        assert len(targets) == len(weights) == len(delays), "%s %s %s" % (
            len(targets), len(weights), len(delays))
        for target, weight, delay in zip(targets, weights, delays):
            if target.local:
                if self.synapse_type is None:
                    self.synapse_type = weight >= 0 and 'excitatory' or 'inhibitory'
                if self.synapse_model == 'Tsodyks-Markram' and 'TM' not in self.synapse_type:
                    self.synapse_type += '_TM'
                synapse_object = getattr(target._cell, self.synapse_type)
                nc = state.parallel_context.gid_connect(
                    int(source), synapse_object)
                nc.weight[0] = weight
                nc.delay = delay
                # nc.threshold is supposed to be set by ParallelContext.threshold, called in _build_cell(), above, but this hasn't been tested
                self.connections.append(Connection(source, target, nc))
Example #8
0
    def connect(self, source, targets, weights, delays):
        """
        Connect a neuron to one or more other neurons with a static connection.
        
        `source`  -- the ID of the pre-synaptic cell.
        `targets` -- a list/1D array of post-synaptic cell IDs, or a single ID.
        `weight`  -- a list/1D array of connection weights, or a single weight.
                     Must have the same length as `targets`.
        `delays`  -- a list/1D array of connection delays, or a single delay.
                     Must have the same length as `targets`.
        """
        #print "connecting", source, "to", targets, "with weights", weights, "and delays", delays
        if not common.is_listlike(targets):
            targets = [targets]
        if isinstance(weights, float):
            weights = [weights]
        if isinstance(delays, float):
            delays = [delays]
        assert len(targets) > 0
        if not isinstance(source, common.IDMixin):
            raise common.ConnectionError(
                "source should be an ID object, actually %s" % type(source))
        for target in targets:
            if not isinstance(target, common.IDMixin):
                raise common.ConnectionError("Invalid target ID: %s" % target)
        assert len(targets) == len(weights) == len(delays), "%s %s %s" % (
            len(targets), len(weights), len(delays))
        if common.is_conductance(targets[0]):
            units = uS
        else:
            units = nA

        synapse_type = self.synapse_type or "excitatory"
        synapse_obj = targets[0].cellclass.synapses[synapse_type]
        try:
            source_group = source.parent_group
        except AttributeError, errmsg:
            raise common.ConnectionError(
                "%s. Maybe trying to connect from non-existing cell (ID=%s)." %
                (errmsg, source))
Example #9
0
    def __init__(self,
                 presynaptic_population,
                 postsynaptic_population,
                 method,
                 source=None,
                 target=None,
                 synapse_dynamics=None,
                 label=None,
                 rng=None):
        """
        presynaptic_population and postsynaptic_population - Population objects.
        
        source - string specifying which attribute of the presynaptic cell
                 signals action potentials
                 
        target - string specifying which synapse on the postsynaptic cell to
                 connect to
                 
        If source and/or target are not given, default values are used.
        
        method - a Connector object, encapsulating the algorithm to use for
                 connecting the neurons.
        
        synapse_dynamics - a `SynapseDynamics` object specifying which
        synaptic plasticity mechanisms to use.
        
        rng - specify an RNG object to be used by the Connector..
        """
        """
           PCSIM implementation specific comments:
               - source parameter does not have any meaning in context of PyPCSIM interface. Action potential
               signals are predefined by the neuron model and each cell has only one source, 
               so there is no need to name a source since is implicitly known. 
               - rng parameter is also not currently not applicable. For connection making only internal
               random number generators can be used.
               - The semantics of the target parameter is slightly changed:
                   If it is a string then it represents a pcsim synapse class.
                   If it is an integer then it represents which target(synapse) on the postsynaptic cell
                   to connect to.
                   It can be also a pcsim SimObjectFactory object which will be used for creation 
                   of the synapse objects associated to the created connections.
                   
        """

        common.Projection.__init__(self, presynaptic_population,
                                   postsynaptic_population, method, source,
                                   target, synapse_dynamics, label, rng)
        self.is_conductance = self.post.celltype.__class__.conductance_based
        self.synapse_shape = ("alpha" in self.post.celltype.__class__.__name__
                              ) and "alpha" or "exp"

        ### Determine connection decider
        ##decider, wiring_method, weight, delay = method.connect(self)
        ##
        ##weight = self.getWeight(weight)
        ##self.is_conductance = hasattr(self.post.pcsim_population.object(0),'ErevExc')
        ##
        ##if isinstance(weight, pyNN.random.RandomDistribution) or hasattr(weight, '__len__'):
        ##    w = 1.
        ##else:
        ##    w = self.convertWeight(weight, self.is_conductance)
        ##
        ##delay  = self.getDelay(delay)
        ##if isinstance(delay, pyNN.random.RandomDistribution) or hasattr(delay, '__len__'):
        ##    d = simulator.state.min_delay/1000.
        ##else:
        ##    d = self.convertDelay(delay)
        ##
        # handle synapse dynamics
        if common.is_listlike(method.weights):
            w = method.weights[0]
        elif hasattr(method.weights, "next"):  # random distribution
            w = 0.0  # actual value used here shouldn't matter. Actual values will be set in the Connector.
        else:
            w = method.weights
        if common.is_listlike(method.delays):
            d = min(method.delays)
        elif hasattr(method.delays, "next"):  # random distribution
            d = get_min_delay(
            )  # actual value used here shouldn't matter. Actual values will be set in the Connector.
        else:
            d = method.delays

        plasticity_parameters = {}
        if self.synapse_dynamics:

            # choose the right model depending on whether we have conductance- or current-based synapses
            if self.is_conductance:
                possible_models = get_synapse_models("Cond")
            else:
                possible_models = get_synapse_models("Curr").union(
                    get_synapse_models("CuBa"))
            if self.synapse_shape == 'alpha':
                possible_models = possible_models.intersection(
                    get_synapse_models("Alpha"))
            else:
                possible_models = possible_models.intersection(
                    get_synapse_models("Exp")).difference(
                        get_synapse_models("DoubleExp"))
            if not self.is_conductance and self.synapse_shape is "exp":
                possible_models.add("StaticStdpSynapse")
                possible_models.add("StaticSpikingSynapse")
                possible_models.add("DynamicStdpSynapse")
                possible_models.add("DynamicSpikingSynapse")

            # we need to know the synaptic time constant, which is a property of the
            # post-synaptic cell in PyNN. Here, we get it from the Population initial
            # value, but this is a problem if tau_syn varies from cell to cell
            if target in (None, 'excitatory'):
                tau_syn = self.post.celltype.parameters['TauSynExc']
                if self.is_conductance:
                    e_syn = self.post.celltype.parameters['ErevExc']
            elif target == 'inhibitory':
                tau_syn = self.post.celltype.parameters['TauSynInh']
                if self.is_conductance:
                    e_syn = self.post.celltype.parameters['ErevInh']
            else:
                raise Exception(
                    "Currently, target must be one of 'excitatory', 'inhibitory' with dynamic synapses"
                )

            if self.is_conductance:
                plasticity_parameters.update(Erev=e_syn)
                weight_scale_factor = 1e-6
            else:
                weight_scale_factor = 1e-9

            if self.synapse_dynamics.fast:
                possible_models = possible_models.intersection(
                    self.short_term_plasticity_mechanism)
                plasticity_parameters.update(
                    self._short_term_plasticity_parameters)
                # perhaps need to ensure that STDP is turned off here, to be turned back on by the next block
            else:
                possible_models = possible_models.difference(
                    dynamic_synapse_models)  # imported from synapses module
            if self.synapse_dynamics.slow:
                possible_models = possible_models.intersection(
                    self.long_term_plasticity_mechanism)
                plasticity_parameters.update(self._stdp_parameters)
                dendritic_delay = self.synapse_dynamics.slow.dendritic_delay_fraction * d
                transmission_delay = d - dendritic_delay
                plasticity_parameters.update({
                    'back_delay': 2 * 0.001 * dendritic_delay,
                    'Winit': w * weight_scale_factor
                })
                # hack to work around the limitations of the translation method
                if self.is_conductance:
                    for name in self.synapse_dynamics.slow.weight_dependence.scales_with_weight:
                        plasticity_parameters[
                            name] *= 1e3  # a scale factor of 1e-9 is always applied in the translation stage
            else:
                possible_models = possible_models.difference(
                    stdp_synapse_models)
                plasticity_parameters.update({'W': w * weight_scale_factor})

            if len(possible_models) == 0:
                raise common.NoModelAvailableError(
                    "The synapse model requested is not available.")
            synapse_type = getattr(pypcsim, list(possible_models)[0])
            try:
                self.syn_factory = synapse_type(delay=d,
                                                tau=tau_syn,
                                                **plasticity_parameters)
            except Exception, err:
                err.args = (
                    "%s\nActual arguments were: delay=%g, tau=%g, plasticity_parameters=%s"
                    % (err.message, d, tau_syn,
                       plasticity_parameters), ) + err.args[1:]
                raise
Example #10
0
        if common.is_number(value):
            for c in self:
                setattr(c, name, value)
        elif isinstance(value, numpy.ndarray) and len(value.shape) == 2:
            offset = (self.parent.pre.first_id, self.parent.post.first_id)
            for c in self.connections:
                addr = (c.source - offset[0], c.target - offset[1])
                try:
                    val = value[addr]
                except IndexError, e:
                    raise IndexError("%s. addr=%s" % (e, addr))
                if numpy.isnan(val):
                    raise Exception(
                        "Array contains no value for synapse from %d to %d" %
                        (c.source, c.target))
                else:
                    setattr(c, name, val)
        elif common.is_listlike(value):
            for c, val in zip(self.connections, value):
                setattr(c, name, val)
        else:
            raise TypeError(
                "Argument should be a numeric type (int, float...), a list, or a numpy array."
            )


# --- Initialization, and module attributes ------------------------------------

net = None
state = _State()
del _State
Example #11
0
class ConnectionManager(object):
    """
    Manage synaptic connections, providing methods for creating, listing,
    accessing individual connections.
    """
    def __init__(self, synapse_type, synapse_model=None, parent=None):
        """
        Create a new ConnectionManager.
        
        `synapse_model` -- either None or 'Tsodyks-Markram'.
        `parent` -- the parent `Projection`, if any.
        """
        global connection_managers
        self.connections = []
        self.parent = parent
        self.synapse_type = synapse_type
        self.synapse_model = synapse_model
        connection_managers.append(self)

    def __getitem__(self, i):
        """Return the `i`th connection on the local MPI node."""
        return self.connections[i]

    def __len__(self):
        """Return the number of connections on the local MPI node."""
        return len(self.connections)

    def __iter__(self):
        """Return an iterator over all connections on the local MPI node."""
        return iter(self.connections)

    def connect(self, source, targets, weights, delays):
        """
        Connect a neuron to one or more other neurons with a static connection.
        
        `source`  -- the ID of the pre-synaptic cell.
        `targets` -- a list/1D array of post-synaptic cell IDs, or a single ID.
        `weight`  -- a list/1D array of connection weights, or a single weight.
                     Must have the same length as `targets`.
        `delays`  -- a list/1D array of connection delays, or a single delay.
                     Must have the same length as `targets`.
        """
        if not isinstance(source,
                          int) or source > state.gid_counter or source < 0:
            errmsg = "Invalid source ID: %s (gid_counter=%d)" % (
                source, state.gid_counter)
            raise common.ConnectionError(errmsg)
        if not common.is_listlike(targets):
            targets = [targets]
        if isinstance(weights, float):
            weights = [weights]
        if isinstance(delays, float):
            delays = [delays]
        assert len(targets) > 0
        for target in targets:
            if not isinstance(target, common.IDMixin):
                raise common.ConnectionError("Invalid target ID: %s" % target)

        assert len(targets) == len(weights) == len(delays), "%s %s %s" % (
            len(targets), len(weights), len(delays))
        for target, weight, delay in zip(targets, weights, delays):
            if target.local:
                if self.synapse_type is None:
                    self.synapse_type = weight >= 0 and 'excitatory' or 'inhibitory'
                if self.synapse_model == 'Tsodyks-Markram' and 'TM' not in self.synapse_type:
                    self.synapse_type += '_TM'
                synapse_object = getattr(target._cell, self.synapse_type)
                nc = state.parallel_context.gid_connect(
                    int(source), synapse_object)
                nc.weight[0] = weight
                nc.delay = delay
                # nc.threshold is supposed to be set by ParallelContext.threshold, called in _build_cell(), above, but this hasn't been tested
                self.connections.append(Connection(source, target, nc))

    def get(self, parameter_name, format, offset=(0, 0)):
        """
        Get the values of a given attribute (weight, delay, etc) for all
        connections on the local MPI node.
        
        `parameter_name` -- name of the attribute whose values are wanted.
        `format` -- "list" or "array". Array format implicitly assumes that all
                    connections belong to a single Projection.
        `offset` -- an (i,j) tuple giving the offset to be used in converting
                    source and target IDs to array indices.
        
        Return a list or a 2D Numpy array. The array element X_ij contains the
        attribute value for the connection from the ith neuron in the pre-
        synaptic Population to the jth neuron in the post-synaptic Population,
        if a single such connection exists. If there are no such connections,
        X_ij will be NaN. If there are multiple such connections, the summed
        value will be given, which makes some sense for weights, but is
        pretty meaningless for delays. 
        """
        if format == 'list':
            values = [getattr(c, parameter_name) for c in self.connections]
        elif format == 'array':
            values = numpy.nan * numpy.ones(
                (self.parent.pre.size, self.parent.post.size))
            for c in self.connections:
                value = getattr(c, parameter_name)
                addr = (c.source - offset[0], c.target - offset[1])
                if numpy.isnan(values[addr]):
                    values[addr] = value
                else:
                    values[addr] += value
        else:
            raise Exception("format must be 'list' or 'array'")
        return values

    def set(self, name, value):
        """
        Set connection attributes for all connections on the local MPI node.
        
        `name`  -- attribute name
        `value` -- the attribute numeric value, or a list/1D array of such
                   values of the same length as the number of local connections,
                   or a 2D array with the same dimensions as the connectivity
                   matrix (as returned by `get(format='array')`).
        """
        if common.is_number(value):
            for c in self:
                setattr(c, name, value)
        elif isinstance(value, numpy.ndarray) and len(value.shape) == 2:
            offset = (self.parent.pre.first_id, self.parent.post.first_id)
            for c in self.connections:
                addr = (c.source - offset[0], c.target - offset[1])
                try:
                    val = value[addr]
                except IndexError, e:
                    raise IndexError("%s. addr=%s" % (e, addr))
                if numpy.isnan(val):
                    raise Exception(
                        "Array contains no value for synapse from %d to %d" %
                        (c.source, c.target))
                else:
                    setattr(c, name, val)
        elif common.is_listlike(value):
            for c, val in zip(self.connections, value):
                setattr(c, name, val)