Example #1
0
    def _divergent_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 core.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 errors.ConnectionError("source should be an ID object, actually %s" % type(source))
        for target in targets:
            if not isinstance(target, common.IDMixin):
                raise errors.ConnectionError("Invalid target ID: %s" % target)
        assert len(targets) == len(weights) == len(delays), "%s %s %s" % (len(targets), len(weights), len(delays))
        synapse_type = self.synapse_type or "excitatory"
        delays = numpy.array(delays).astype(numpy.int).tolist()
        if self.synapse_type == 'inhibitory' and common.is_conductance(targets[0]):
            weights *= -1  # NEMO wants negative values for inhibitory weights, even if these are conductances
        if isinstance(weights, numpy.ndarray):
            weights = weights.tolist()
        source = int(source)
        synapses = simulator.state.net.add_synapse(source, targets, delays, weights, self._is_plastic)
        self._sources.append(source)
        self._connections += [(synapses[0], synapses[-1])]
Example #2
0
    def connect(self, source, targets, weights, delays, homogeneous=False):
        """
        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 core.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 errors.ConnectionError("source should be an ID object, actually %s" % type(source))
        for target in targets:
            if not isinstance(target, common.IDMixin):
                raise errors.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"
        try:
            source_group = source.parent_group
        except AttributeError, errmsg:
            raise errors.ConnectionError("%s. Maybe trying to connect from non-existing cell (ID=%s)." % (errmsg, source))
Example #3
0
    def _divergent_connect(self, source, targets, weights, delays, homogeneous=False):
        """
        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 core.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 errors.ConnectionError("source should be an ID object, actually %s" % type(source))
        for target in targets:
            if not isinstance(target, common.IDMixin):
                raise errors.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"
        try:
            source_group = source.parent_group
        except AttributeError, errmsg:
            raise errors.ConnectionError("%s. Maybe trying to connect from non-existing cell (ID=%s)." % (errmsg, source))
Example #4
0
    def connect(self, projection):
        """Connect-up a Projection."""
        if isinstance(projection.rng, random.NativeRNG):
            raise Exception("Warning: use of NativeRNG not implemented.")
            
        for target in projection.post.local_cells.flat:
            # pick n neurons at random
            if hasattr(self, 'rand_distr'):
                n = self.rand_distr.next()
            else:
                n = self.n

            candidates = projection.pre.all_cells.flatten().tolist()
            if not self.allow_self_connections and projection.pre == projection.post:
                candidates.remove(target)
            sources = []
            while len(sources) < n: # if the number of requested cells is larger than the size of the
                                    # presynaptic population, we allow multiple connections for a given cell
                sources += [candidates[candidates.index(id)] for id in projection.rng.permutation(candidates)[0:n]]
                # have to use index() because rng.permutation returns ints, not ID objects
            sources = sources[:n]
            
            weights = self.get_weights(n)
            is_conductance = common.is_conductance(projection.post.index(0))
            weights = common.check_weight(weights, projection.synapse_type, is_conductance)
            delays = self.get_delays(n)
            
            projection.connection_manager.convergent_connect(sources, [target], weights, delays)
Example #5
0
 def _divergent_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 core.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 errors.ConnectionError("source should be an ID object, actually %s" % type(source))
     for target in targets:
         if not isinstance(target, common.IDMixin):
             raise errors.ConnectionError("Invalid target ID: %s" % target)
     assert len(targets) == len(weights) == len(delays), "%s %s %s" % (len(targets),len(weights),len(delays))
     synapse_type = self.synapse_type or "excitatory"
     delays = numpy.array(delays).astype(numpy.int).tolist()
     if self.synapse_type == 'inhibitory' and common.is_conductance(targets[0]):
         weights *= -1 # NEMO wants negative values for inhibitory weights, even if these are conductances
     if isinstance(weights, numpy.ndarray):
         weights = weights.tolist()    
     source   = int(source)        
     synapses = simulator.state.net.add_synapse(source, targets, delays, weights, self._is_plastic)
     self._sources.append(source)
     self._connections += [(synapses[0], synapses[-1])]
Example #6
0
 def _get_weight(self):
     """Synaptic weight in nA or µS."""
     w_nA = nest.GetStatus(self.id(), 'weight')[0]
     if self.parent.synapse_type == 'inhibitory' and common.is_conductance(
             self.target):
         w_nA *= -1  # NEST uses negative values for inhibitory weights, even if these are conductances
     return 0.001 * w_nA
Example #7
0
 def get(self, parameter_name, format):
     """
     Get the values of a given attribute (weight or delay) for all
     connections in this manager.
     
     `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.
     
     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 parameter_name not in ('weight', 'delay'):
         translated_name = None
         if self.parent.synapse_dynamics.fast and parameter_name in self.parent.synapse_dynamics.fast.translations:
             translated_name = self.parent.synapse_dynamics.fast.translations[parameter_name]["translated_name"] # this is a hack that works because there are no units conversions
         elif self.parent.synapse_dynamics.slow:
             for component_name in "timing_dependence", "weight_dependence", "voltage_dependence":
                 component = getattr(self.parent.synapse_dynamics.slow, component_name)
                 if component and parameter_name in component.translations:
                     translated_name = component.translations[parameter_name]["translated_name"]
                     break
         if translated_name:
             parameter_name = translated_name
         else:
             raise Exception("synapse type does not have an attribute '%s', or else this attribute is not accessible." % parameter_name)
     if format == 'list':
         values = nest.GetStatus(self.connections, parameter_name)
         if parameter_name == "weight":
             values = [0.001*val for val in values]
     elif format == 'array':
         value_arr = numpy.nan * numpy.ones((self.parent.pre.size, self.parent.post.size))
         connection_parameters = nest.GetStatus(self.connections, ('source', 'target', parameter_name))
         for conn in connection_parameters: 
             # don't need to pass offset as arg, now we store the parent projection
             # (offset is always 0,0 for connections created with connect())
             src, tgt, value = conn
             addr = self.parent.pre.id_to_index(src), self.parent.post.id_to_index(tgt)
             if numpy.isnan(value_arr[addr]):
                 value_arr[addr] = value
             else:
                 value_arr[addr] += value
         if parameter_name == 'weight':
             value_arr *= 0.001
             if self.synapse_type == 'inhibitory' and common.is_conductance(self[0].target):
                 value_arr *= -1 # NEST uses negative values for inhibitory weights, even if these are conductances
         values = value_arr
     else:
         raise Exception("format must be 'list' or 'array', actually '%s'" % format)
     return values
Example #8
0
 def get(self, parameter_name, format, gather=True):
     """
     Get the values of a given attribute (weight or delay) for all
     connections in this Projection.
     
     `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.
     
     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 parameter_name not in ('weight', 'delay'):
         translated_name = None
         if self.synapse_dynamics.fast and parameter_name in self.synapse_dynamics.fast.translations:
             translated_name = self.synapse_dynamics.fast.translations[parameter_name]["translated_name"] # this is a hack that works because there are no units conversions
         elif self.synapse_dynamics.slow:
             for component_name in "timing_dependence", "weight_dependence", "voltage_dependence":
                 component = getattr(self.synapse_dynamics.slow, component_name)
                 if component and parameter_name in component.translations:
                     translated_name = component.translations[parameter_name]["translated_name"]
                     break
         if translated_name:
             parameter_name = translated_name
         else:
             raise Exception("synapse type does not have an attribute '%s', or else this attribute is not accessible." % parameter_name)
     if format == 'list':
         values = nest.GetStatus(self.connections, parameter_name)
         if parameter_name == "weight":
             values = [0.001*val for val in values]
     elif format == 'array':
         value_arr = numpy.nan * numpy.ones((self.pre.size, self.post.size))
         connection_parameters = nest.GetStatus(self.connections, ('source', 'target', parameter_name))
         for conn in connection_parameters: 
             # (offset is always 0,0 for connections created with connect())
             src, tgt, value = conn
             addr = self.pre.id_to_index(src), self.post.id_to_index(tgt)
             if numpy.isnan(value_arr[addr]):
                 value_arr[addr] = value
             else:
                 value_arr[addr] += value
         if parameter_name == 'weight':
             value_arr *= 0.001
             if self.synapse_type == 'inhibitory' and common.is_conductance(self[0].target):
                 value_arr *= -1 # NEST uses negative values for inhibitory weights, even if these are conductances
         values = value_arr
     else:
         raise Exception("format must be 'list' or 'array', actually '%s'" % format)
     return values
Example #9
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 #10
0
    def _convergent_connect(self, sources, target, weights, delays):
        """
        Connect a neuron to one or more other neurons with a static connection.

        `sources`  -- a list/1D array of pre-synaptic cell IDs, or a single ID.
        `target` -- the ID of the post-synaptic cell.
        `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(target, (int, long)) or target < 0:
            errmsg = "Invalid target ID: %s" % target
            raise errors.ConnectionError(errmsg)
        if not core.is_listlike(sources):
            sources = [sources]
        if isinstance(weights, float):
            weights = [weights]
        if isinstance(delays, float):
            delays = [delays]
        assert len(sources) > 0
        for source in sources:
            if not isinstance(source, common.IDMixin):
                raise errors.ConnectionError("Invalid source ID: %s" % source)
        assert len(sources) == len(weights) == len(delays), "%s %s %s" % (
            len(sources), len(weights), len(delays))
        if common.is_conductance(target):
            weight_scale_factor = 1e-6  # Convert from µS to S
        else:
            weight_scale_factor = 1e-9  # Convert from nA to A

        synapse_type = self.syn_factory or "excitatory"
        if isinstance(synapse_type, basestring):
            syn_target_id = Projection.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 errors.ConnectionError(
                "synapse_type must be a string or a PCSIM synapse factory. Actual type is %s"
                % type(synapse_type))
        for source, weight, delay in zip(sources, weights, delays):
            syn_factory.W = weight * weight_scale_factor
            syn_factory.delay = delay * 0.001  # ms --> s
            try:
                c = simulator.net.connect(source, target, syn_factory)
            except RuntimeError as e:
                raise errors.ConnectionError(e)
            if target.local:
                self.connections.append(
                    simulator.Connection(source, target,
                                         simulator.net.object(c),
                                         1.0 / weight_scale_factor))
Example #11
0
    def _divergent_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 core.is_listlike(source):
            assert len(source) == 1
            source = source[0]
        if not core.is_listlike(targets):
            targets = [targets]
        assert len(targets) > 0

        if self.synapse_type not in targets[0].celltype.synapse_types:
            raise errors.ConnectionError(
                "User gave synapse_type=%s, synapse_type must be one of: %s" %
                (self.synapse_type,
                 "'" + "', '".join(st
                                   for st in targets[0].celltype.synapse_types
                                   or ['*No connections supported*'])) + "'")
        weights = numpy.array(
            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  # 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]

        if targets[0].celltype.standard_receptor_type:
            try:
                nest.DivergentConnect([source], targets, weights, delays,
                                      self.synapse_model)
            except nest.NESTError, e:
                raise errors.ConnectionError(
                    "%s. source=%s, targets=%s, weights=%s, delays=%s, synapse model='%s'"
                    %
                    (e, source, targets, weights, delays, self.synapse_model))
Example #12
0
    def _convergent_connect(self, sources, target, weights, delays):
        """
        Connect a neuron to one or more other neurons with a static connection.
        
        `sources`  -- a list/1D array of pre-synaptic cell IDs, or a single ID.
        `target` -- the ID of the post-synaptic cell.
        `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(target, (int, long)) or target < 0:
            errmsg = "Invalid target ID: %s" % target
            raise errors.ConnectionError(errmsg)
        if not core.is_listlike(sources):
            sources = [sources]
        if isinstance(weights, float):
            weights = [weights]
        if isinstance(delays, float):
            delays = [delays]
        assert len(sources) > 0
        for source in sources:
            if not isinstance(source, common.IDMixin):
                raise errors.ConnectionError("Invalid source ID: %s" % source)
        assert len(sources) == len(weights) == len(delays), "%s %s %s" % (len(sources), len(weights), len(delays))
        if common.is_conductance(target):
            weight_scale_factor = 1e-6  # Convert from µS to S
        else:
            weight_scale_factor = 1e-9  # Convert from nA to A

        synapse_type = self.syn_factory or "excitatory"
        if isinstance(synapse_type, basestring):
            syn_target_id = Projection.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 errors.ConnectionError(
                "synapse_type must be a string or a PCSIM synapse factory. Actual type is %s" % type(synapse_type)
            )
        for source, weight, delay in zip(sources, weights, delays):
            syn_factory.W = weight * weight_scale_factor
            syn_factory.delay = delay * 0.001  # ms --> s
            try:
                c = simulator.net.connect(source, target, syn_factory)
            except RuntimeError, e:
                raise errors.ConnectionError(e)
            if target.local:
                self.connections.append(
                    simulator.Connection(source, target, simulator.net.object(c), 1.0 / weight_scale_factor)
                )
Example #13
0
    def connect(self, projection):
        """Connect-up a Projection."""
        if isinstance(projection.rng, random.NativeRNG):
            raise Exception("Warning: use of NativeRNG not implemented.")

        for source in projection.pre.all_cells.flat:
            # pick n neurons at random
            if hasattr(self, 'rand_distr'):
                n = self.rand_distr.next()
            else:
                n = self.n

            candidates = projection.post.all_cells.flatten().tolist()
            if not self.allow_self_connections and projection.pre == projection.post:
                candidates.remove(source)
            targets = []
            while len(
                    targets
            ) < n:  # if the number of requested cells is larger than the size of the
                # postsynaptic population, we allow multiple connections for a given cell
                targets += [
                    candidates[candidates.index(id)]
                    for id in projection.rng.permutation(candidates)[0:n]
                ]
                # have to use index() because rng.permutation returns ints, not ID objects

            targets = numpy.array(targets[:n], dtype=common.IDMixin)

            weights = self.get_weights(n)
            is_conductance = common.is_conductance(projection.post.index(0))
            weights = common.check_weight(weights, projection.synapse_type,
                                          is_conductance)
            delays = self.get_delays(n)

            #local = numpy.array([tgt.local for tgt in targets])
            #if local.size > 0:
            #    targets = targets[local]
            #    weights = weights[local]
            #    delays = delays[local]
            targets = targets.tolist()
            #print common.rank(), source, targets
            if len(targets) > 0:
                projection.connection_manager.connect(source, targets, weights,
                                                      delays)
Example #14
0
    def _convergent_connect(self, sources, target, weights, delays):
        """
        Connect one or more neurons to a single post-synaptic neuron.
        `sources` -- a list/1D array of pre-synaptic cell IDs, or a single ID.
        `target`  -- the ID of the post-synaptic cell.
        `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 core.is_listlike(target):
            assert len(target) == 1
            target = target[0]
        if not core.is_listlike(sources):
            sources = [sources]
        assert len(sources) > 0, sources
        if self.synapse_type not in ('excitatory', 'inhibitory', None):
            raise errors.ConnectionError(
                "synapse_type must be 'excitatory', 'inhibitory', or None (equivalent to 'excitatory')"
            )
        weights = numpy.array(
            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(target):
            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.ConvergentConnect(sources, [target], weights, delays,
                                   self.synapse_model)
        except nest.NESTError, e:
            raise errors.ConnectionError(
                "%s. sources=%s, target=%s, weights=%s, delays=%s, synapse model='%s'"
                % (e, sources, target, weights, delays, self.synapse_model))
Example #15
0
 def _divergent_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 core.is_listlike(source):
         assert len(source) == 1
         source = source[0]
     if not core.is_listlike(targets):
         targets = [targets]
     assert len(targets) > 0
     
     if self.synapse_type not in targets[0].celltype.synapse_types:
         raise errors.ConnectionError("User gave synapse_type=%s, synapse_type must be one of: %s" % ( self.synapse_type, "'"+"', '".join(st for st in targets[0].celltype.synapse_types or ['*No connections supported*']))+"'" )
     weights = numpy.array(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 # 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]
     
     if targets[0].celltype.standard_receptor_type:
         try:
             nest.DivergentConnect([source], targets, weights, delays, self.synapse_model)            
         except nest.NESTError, e:
             raise errors.ConnectionError("%s. source=%s, targets=%s, weights=%s, delays=%s, synapse model='%s'" % (
                                          e, source, targets, weights, delays, self.synapse_model))
Example #16
0
    def connect(self, projection):
        """Connect-up a Projection."""
        if projection.pre.dim == projection.post.dim:
            N = projection.post.size
            local = projection.post._mask_local.flatten()
            weights = self.get_weights(N, local)
            is_conductance = common.is_conductance(projection.post.index(0))
            weights = common.check_weight(weights, projection.synapse_type,
                                          is_conductance)
            delays = self.get_delays(N, local)

            for tgt, w, d in zip(projection.post.local_cells, weights, delays):
                src = projection.pre.index(projection.post.id_to_index(tgt))

                # the float is in case the values are of type numpy.float64, which NEST chokes on
                projection.connection_manager.connect(src, [tgt], float(w),
                                                      float(d))
        else:
            raise common.InvalidDimensionsError(
                "OneToOneConnector does not support presynaptic and postsynaptic Populations of different sizes."
            )
Example #17
0
 def _convergent_connect(self, sources, target, weights, delays):
     """
     Connect one or more neurons to a single post-synaptic neuron.
     `sources` -- a list/1D array of pre-synaptic cell IDs, or a single ID.
     `target`  -- the ID of the post-synaptic cell.
     `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 core.is_listlike(target):
         assert len(target) == 1
         target = target[0]
     if not core.is_listlike(sources):
         sources = [sources]
     assert len(sources) > 0, sources
     if self.synapse_type not in ('excitatory', 'inhibitory', None):
         raise errors.ConnectionError("synapse_type must be 'excitatory', 'inhibitory', or None (equivalent to 'excitatory')")
     weights = numpy.array(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(target):
         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.ConvergentConnect(sources, [target], weights, delays, self.synapse_model)            
     except nest.NESTError, e:
         raise errors.ConnectionError("%s. sources=%s, target=%s, weights=%s, delays=%s, synapse model='%s'" % (
                                      e, sources, target, weights, delays, self.synapse_model))
Example #18
0
 def _get_weight(self):
     """Synaptic weight in nA or µS."""
     w_nA = nest.GetStatus([self.id()], 'weight')[0]
     if self.parent.synapse_type == 'inhibitory' and common.is_conductance(self.target):
         w_nA *= -1  # NEST uses negative values for inhibitory weights, even if these are conductances
     return 0.001 * w_nA
Example #19
0
                    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
        if core.is_listlike(value):
            value = numpy.array(value)
        else:
            value = float(value)

        if name == 'weight':
            value *= 1000.0
            if self.synapse_type == 'inhibitory' and common.is_conductance(self.post[0]):
                value *= -1 # NEST wants negative values for inhibitory weights, even if these are conductances
        elif name == 'delay':
            pass
        else:
            #translation = self.synapse_dynamics.reverse_translate({name: value})
            #name, value = translation.items()[0]
            translated_name = None
            if self.synapse_dynamics.fast:
                if name in self.synapse_dynamics.fast.translations:
                    translated_name = self.synapse_dynamics.fast.translations[name]["translated_name"] # a hack
            if translated_name is None:
                if self.synapse_dynamics.slow:
                    for component_name in "timing_dependence", "weight_dependence", "voltage_dependence":
                        component = getattr(self.synapse_dynamics.slow, component_name)
                        if component and name in component.translations:
Example #20
0
    def connect(self, projection):
        """Connect-up a Projection."""
        # Timers
        global rank
        timer0 = 0.0
        timer1 = 0.0
        timer2 = 0.0
        timer3 = 0.0
        timer4 = 0.0
        
        # Recuperate variables #
        n = self.n
        dist_factor = self.dist_factor
        noise_factor = self.noise_factor
        
        # Do some checking #
        assert dist_factor >= 0
        assert noise_factor >= 0
        if isinstance(n, int):
            assert n >= 0
        else:
            raise Exception("n must be an integer.")
        
        # Get posts and pres #
        listPostIDs = projection.post.local_cells
        listPreIDs = projection.pre.all_cells
        countPost = len(listPostIDs)
        countPre = len(listPreIDs)        
        listPreIndexes = numpy.arange(countPre)
        listPostIndexes = map(projection.post.id_to_index, listPostIDs)

        # Prepare all distances #
        allDistances = self.space.distances(projection.post.positions,projection.pre.positions)            
        
        # Get weights #
        weights = numpy.empty(n)
        weights[:] = self.weights
        is_conductance = common.is_conductance(projection.post[listPostIndexes[0]])
        weights = common.check_weight(weights, projection.synapse_type, is_conductance)

        numpy.random.seed(12345)
        
        for i in xrange(len(listPostIDs)):
            currentPostIndex = listPostIndexes[i]
            currentPostID = listPostIDs[i]
            #currentPostIDAsList = [currentPostID]
            
            # Pick n neurons at random in pre population
            myTimer = time.time()
            chosenPresIndexes = list(numpy.random.permutation(numpy.arange(countPre))[0:n])
            chosenPresIDs = list(projection.pre[chosenPresIndexes].all_cells)
            #if rank==0:
            #    print(chosenPresIDs)
            #chosenPresIDs = chosenPresIDs.tolist()
            timer0 += time.time() - myTimer
            
            # Get distances
            myTimer = time.time()
            #distances = allDistances[currentPostIndex,chosenPresIndexes]
            distances = allDistances[currentPostIndex,chosenPresIndexes]
            timer1 += time.time() - myTimer
                        
            # Generate gamme noise
            noise = numpy.random.gamma(1.0, noise_factor, n)
                
            # Create delays with distance and noise
            myTimer = time.time()
            delays = dist_factor * distances * (1.0+noise)
            timer2 += time.time() - myTimer
            #delays[:] = 1.0
                        
            # Check for small and big delays
            myTimer = time.time()
            delaysClipped = numpy.clip(delays,sim.get_min_delay(),sim.get_max_delay())
            howManyClipped = len((delays != delaysClipped).nonzero()[0])
            if (howManyClipped > 1):
                print("Warning: %d of %d delays were cliped because they were either bigger than the max delay or lower than the min delay." % (howManyClipped, n))
            delaysClipped = delaysClipped.tolist()
            timer3 += time.time() - myTimer
                
            # Connect everything up
            yTimer = time.time()
            projection._convergent_connect(chosenPresIDs, currentPostID, weights, delaysClipped)
            timer4 += time.time() - myTimer
            
        
        # Print timings
        if rank==0:
            print("\033[2;46m" + ("Timer 0: %5.4f seconds" % timer0).ljust(60) + "\033[m")
            print("\033[2;46m" + ("Timer 1: %5.4f seconds" % timer1).ljust(60) + "\033[m")
            print("\033[2;46m" + ("Timer 2: %5.4f seconds" % timer2).ljust(60) + "\033[m")
            print("\033[2;46m" + ("Timer 3: %5.4f seconds" % timer3).ljust(60) + "\033[m")
            print("\033[2;46m" + ("Timer 4: %5.4f seconds" % timer4).ljust(60) + "\033[m")
Example #21
0
def test_is_conductance():
    for cb in (True, False):
        cell = MockCell(build_cellclass(cb))
        assert common.is_conductance(cell) == cb
Example #22
0
def test_is_conductance_with_nonlocal_cell():
    cell = MockCell(build_cellclass(True), local=False)
    assert common.is_conductance(cell) is None
Example #23
0
    def connect(self, projection):
        """Connect-up a Projection."""
        # Timers
        global rank
        timer0 = 0.0
        timer1 = 0.0
        timer2 = 0.0
        timer3 = 0.0
        timer4 = 0.0
        
        # Recuperate variables #
        n = self.n
        dist_factor = self.dist_factor
        noise_factor = self.noise_factor
        
        # Do some checking #
        assert dist_factor >= 0
        assert noise_factor >= 0
        if isinstance(n, int):
            assert n >= 0
        else:
            raise Exception("n must be an integer.")
        
        # Get posts and pres #
        listPostIDs = projection.post.local_cells
        listPreIDs = projection.pre.all_cells
        countPost = len(listPostIDs)
        countPre = len(listPreIDs)        
        listPreIndexes = numpy.arange(countPre)
        listPostIndexes = map(projection.post.id_to_index, listPostIDs)

        # Prepare all distances #
        allDistances = self.space.distances(projection.post.positions, projection.pre.positions)            
        
        # Get weights #
        weights = numpy.empty(n)
        weights[:] = self.weights
        is_conductance = common.is_conductance(projection.post[listPostIndexes[0]])
        weights = common.check_weight(weights, projection.synapse_type, is_conductance)
        
        for i in xrange(len(listPostIDs)):
            currentPostIndex = listPostIndexes[i]
            currentPostID = listPostIDs[i]
            #currentPostIDAsList = [currentPostID]
            
            # Pick n neurons at random in pre population
            myTimer = time.time()
            chosenPresIndexes = list(numpy.random.permutation(numpy.arange(countPre))[0:n])
            chosenPresIDs = list(projection.pre[chosenPresIndexes].all_cells)
            #if rank==0:
            #    print(chosenPresIDs)
            #chosenPresIDs = chosenPresIDs.tolist()
            timer0 += time.time() - myTimer
            
            # Get distances
            myTimer = time.time()
            #distances = allDistances[currentPostIndex,chosenPresIndexes]
            distances = allDistances[currentPostIndex, chosenPresIndexes]
            timer1 += time.time() - myTimer
                        
            # Generate gamme noise
            noise = numpy.random.gamma(1.0, noise_factor, n)
                
            # Create delays with distance and noise
            myTimer = time.time()
            delays = dist_factor * distances * (1.0 + noise)
            timer2 += time.time() - myTimer
            #delays[:] = 1.0
                        
            # Check for small and big delays
            myTimer = time.time()
            delaysClipped = numpy.clip(delays, common.get_min_delay(), common.get_max_delay())
            howManyClipped = len((delays != delaysClipped).nonzero()[0])
            if (howManyClipped > 1):
                print("Warning: %d of %d delays were cliped because they were either bigger than the max delay or lower than the min delay." % (howManyClipped, n))
            delaysClipped = delaysClipped.tolist()
            timer3 += time.time() - myTimer
                
            # Connect everything up
            yTimer = time.time()
            projection._convergent_connect(chosenPresIDs, currentPostID, weights, delaysClipped)
            timer4 += time.time() - myTimer
            
        # Print timings
        if rank == 0:
            print("\033[2;46m" + ("Timer 0: %5.4f seconds" % timer0).ljust(60) + "\033[m")
            print("\033[2;46m" + ("Timer 1: %5.4f seconds" % timer1).ljust(60) + "\033[m")
            print("\033[2;46m" + ("Timer 2: %5.4f seconds" % timer2).ljust(60) + "\033[m")
            print("\033[2;46m" + ("Timer 3: %5.4f seconds" % timer3).ljust(60) + "\033[m")
            print("\033[2;46m" + ("Timer 4: %5.4f seconds" % timer4).ljust(60) + "\033[m")
Example #24
0
 def __init__(self, source, local_mask, projection, safe=True):
     ConnectionAttributeGenerator.__init__(self, source, local_mask, safe)
     self.projection = projection
     self.is_conductance = common.is_conductance(
         projection.post.all_cells[0])
Example #25
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 potentialss

        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.
        """
        common.Projection.__init__(self, presynaptic_population,
                                   postsynaptic_population, method, source,
                                   target, synapse_dynamics, label, rng)
        self._method = method
        self._connections = None

        #if isinstance(presynaptic_population, common.Assembly) or isinstance(postsynaptic_population, common.Assembly):
        #raise Exception("Projections with Assembly objects are not working yet in Brian")

        if self.synapse_dynamics:
            if self.synapse_dynamics.fast:
                if self.synapse_dynamics.slow:
                    raise Exception(
                        "It is not currently possible to have both short-term and long-term plasticity at the same time with this simulator."
                    )
                else:
                    self._plasticity_model = "tsodyks_markram_synapse"
            elif synapse_dynamics.slow:
                self._plasticity_model = "stdp_synapse"
        else:
            self._plasticity_model = "static_synapse"

        self._n = {}
        self._brian_connections = {}
        self._indices = {}
        self._populations = [{}, {}]

        method.connect(self)
        self._finalize()

        if self._plasticity_model != "static_synapse":
            for key in self._brian_connections.keys():
                synapses = self._brian_connections[key]
                if self._plasticity_model is "stdp_synapse":
                    parameters = self.synapse_dynamics.slow.all_parameters
                    if common.is_conductance(self.post[0]):
                        units = uS
                    else:
                        units = nA
                    stdp = simulator.STDP(synapses,
                                          parameters['tau_plus'] * ms,
                                          parameters['tau_minus'] * ms,
                                          parameters['A_plus'],
                                          -parameters['A_minus'],
                                          parameters['mu_plus'],
                                          parameters['mu_minus'],
                                          wmin=parameters['w_min'] * units,
                                          wmax=parameters['w_max'] * units)
                    simulator.state.add(stdp)
                elif self._plasticity_model is "tsodyks_markram_synapse":
                    parameters = self.synapse_dynamics.fast.parameters
                    stp = brian.STP(synapses, parameters['tau_rec'],
                                    parameters['tau_facil'], parameters['U'])
                    simulator.state.add(stp)
Example #26
0
 def __init__(self, source, local_mask, projection, safe=True):
   ConnectionAttributeGenerator.__init__(self, source, local_mask, safe)
   self.projection     = projection
   self.is_conductance = common.is_conductance(projection.post.all_cells[0])
Example #27
0
def test_is_conductance_with_nonlocal_cell():
    cell = MockCell(build_cellclass(True), local=False)
    assert common.is_conductance(cell) is None
Example #28
0
                    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
        if core.is_listlike(value):
            value = numpy.array(value)
        else:
            value = float(value)

        if name == 'weight':
            value *= 1000.0
            if self.synapse_type == 'inhibitory' and common.is_conductance(self[0].target):
                value *= -1 # NEST wants negative values for inhibitory weights, even if these are conductances
        elif name == 'delay':
            pass
        else:
            #translation = self.parent.synapse_dynamics.reverse_translate({name: value})
            #name, value = translation.items()[0]
            translated_name = None
            if self.parent.synapse_dynamics.fast:
                if name in self.parent.synapse_dynamics.fast.translations:
                    translated_name = self.parent.synapse_dynamics.fast.translations[name]["translated_name"] # a hack
            if translated_name is None:
                if self.parent.synapse_dynamics.slow:
                    for component_name in "timing_dependence", "weight_dependence", "voltage_dependence":
                        component = getattr(self.parent.synapse_dynamics.slow, component_name)
                        if component and name in component.translations:
Example #29
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 potentialss

        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.
        """
        common.Projection.__init__(self, presynaptic_population, postsynaptic_population, method,
                                   source, target, synapse_dynamics, label, rng)
        self._method           = method
        self._connections      = None

        #if isinstance(presynaptic_population, common.Assembly) or isinstance(postsynaptic_population, common.Assembly):
            #raise Exception("Projections with Assembly objects are not working yet in Brian")

        if self.synapse_dynamics:
            if self.synapse_dynamics.fast:
                if self.synapse_dynamics.slow:
                    raise Exception("It is not currently possible to have both short-term and long-term plasticity at the same time with this simulator.")
                else:
                    self._plasticity_model = "tsodyks_markram_synapse"
            elif synapse_dynamics.slow:
                self._plasticity_model = "stdp_synapse"
        else:
            self._plasticity_model = "static_synapse"

        self._n                 = {}
        self._brian_connections = {}
        self._indices           = {}
        self._populations      = [{}, {}]

        method.connect(self)
        self._finalize()

        if self._plasticity_model != "static_synapse":
            for key in self._brian_connections.keys():
                synapses = self._brian_connections[key]
                if self._plasticity_model is "stdp_synapse":
                    parameters   = self.synapse_dynamics.slow.all_parameters
                    if common.is_conductance(self.post[0]):
                        units = uS
                    else:
                        units = nA
                    stdp = simulator.STDP(synapses,
                                        parameters['tau_plus'] * ms,
                                        parameters['tau_minus'] * ms,
                                        parameters['A_plus'],
                                        -parameters['A_minus'],
                                        parameters['mu_plus'],
                                        parameters['mu_minus'],
                                        wmin = parameters['w_min'] * units,
                                        wmax = parameters['w_max'] * units)
                    simulator.state.add(stdp)
                elif self._plasticity_model is "tsodyks_markram_synapse":
                    parameters   = self.synapse_dynamics.fast.parameters
                    stp = brian.STP(synapses, parameters['tau_rec'],
                                            parameters['tau_facil'],
                                            parameters['U'])
                    simulator.state.add(stp)
Example #30
0
def test_is_conductance():
    for cb in (True, False):
        cell = MockCell(build_cellclass(cb))
        assert common.is_conductance(cell) == cb
Example #31
0
                    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
        if core.is_listlike(value):
            value = numpy.array(value)
        else:
            value = float(value)

        if name == 'weight':
            value *= 1000.0
            if self.synapse_type == 'inhibitory' and common.is_conductance(
                    self.post[0]):
                value *= -1  # NEST wants negative values for inhibitory weights, even if these are conductances
        elif name == 'delay':
            pass
        else:
            #translation = self.synapse_dynamics.reverse_translate({name: value})
            #name, value = translation.items()[0]
            translated_name = None
            if self.synapse_dynamics.fast:
                if name in self.synapse_dynamics.fast.translations:
                    translated_name = self.synapse_dynamics.fast.translations[
                        name]["translated_name"]  # a hack
            if translated_name is None:
                if self.synapse_dynamics.slow:
                    for component_name in "timing_dependence", "weight_dependence", "voltage_dependence":
                        component = getattr(self.synapse_dynamics.slow,