コード例 #1
0
 def connect(self, projection):
     """Connect-up a Projection."""
     idx = numpy.argsort(self.conn_list[:, 0])
     self.sources = numpy.unique(self.conn_list[:, 0]).astype(int)
     self.candidates = projection.post.local_cells
     self.conn_list = self.conn_list[idx]
     self.progressbar(len(self.sources))
     count = 0
     left = numpy.searchsorted(self.conn_list[:, 0], self.sources, 'left')
     right = numpy.searchsorted(self.conn_list[:, 0], self.sources, 'right')
     #tests = "|".join(['(tgts == %d)' %id for id in self.candidates])
     for src, l, r in zip(self.sources, left, right):
         targets = self.conn_list[l:r, 1].astype(int)
         weights = self.conn_list[l:r, 2]
         delays = self.conn_list[l:r, 3]
         try:
             src = projection.pre.all_cells[src]
         except IndexError:
             raise errors.ConnectionError("invalid source index %s" % src)
         try:
             tgts = projection.post.all_cells[targets]
         except IndexError:
             raise errors.ConnectionError("invalid target index or indices")
         ## We need to exclude the non local cells. Fastidious, need maybe
         ## to use a convergent_connect method, instead of a divergent_connect one
         #idx     = eval(tests)
         #projection.connection_manager.connect(src, tgts[idx].tolist(), weights[idx], delays[idx])
         projection.connection_manager.connect(src, tgts.tolist(), weights,
                                               delays)
         self.progression(count)
         count += 1
コード例 #2
0
ファイル: projections.py プロジェクト: p-muller/PyNN
    def __init__(self, presynaptic_neurons, postsynaptic_neurons, connector,
                 synapse_type=None, source=None, receptor_type=None,
                 space=Space(), label=None):
        """
        Create a new projection, connecting the pre- and post-synaptic neurons.
        """
        for prefix, pop in zip(("pre", "post"),
                               (presynaptic_neurons, postsynaptic_neurons)):
            if not isinstance(pop, (BasePopulation, Assembly)):
                raise errors.ConnectionError("%ssynaptic_neurons must be a Population, PopulationView or Assembly, not a %s" % (prefix, type(pop)))

        if isinstance(postsynaptic_neurons, Assembly):
            if not postsynaptic_neurons._homogeneous_synapses:
                raise errors.ConnectionError('Projection to an Assembly object can be made only with homogeneous synapses types')

        self.pre    = presynaptic_neurons  #  } these really
        self.source = source               #  } should be
        self.post   = postsynaptic_neurons #  } read-only
        self.receptor_type = receptor_type or 'excitatory'  # TO FIX: if weights are negative, default should be 'inhibitory'
        if self.receptor_type not in postsynaptic_neurons.receptor_types:
            valid_types = postsynaptic_neurons.receptor_types
            assert len(valid_types) > 0
            errmsg = "User gave synapse_type=%s, synapse_type must be one of: '%s'"
            raise errors.ConnectionError(errmsg % (self.receptor_type, "', '".join(valid_types)))
        self.label = label
        self.space = space
        self._connector = connector
        self.synapse_type = synapse_type or self._static_synapse_class()
        assert isinstance(self.synapse_type, models.BaseSynapseType), \
              "The synapse_type argument must be a models.BaseSynapseType object, not a %s" % type(synapse_type)
        if label is None:
            if self.pre.label and self.post.label:
                self.label = "%s→%s" % (self.pre.label, self.post.label)
        Projection._nProj += 1
コード例 #3
0
ファイル: __init__.py プロジェクト: sanjayankur31/PyNN
def check_weights(weights, projection):
    # if projection.post is an Assembly, some components might have cond-synapses, others curr,
    # so need a more sophisticated check here. For now, skipping check and emitting a warning
    if hasattr(projection.post, "_homogeneous_synapses"
               ) and not projection.post._homogeneous_synapses:
        warnings.warn(
            "Not checking weights due to due mixture of synapse types")
    if isinstance(weights, np.ndarray):
        all_negative = (weights <= 0).all()
        all_positive = (weights >= 0).all()
        if not (all_negative or all_positive):
            raise errors.ConnectionError(
                "Weights must be either all positive or all negative")
    elif np.isreal(weights):
        all_positive = weights >= 0
        all_negative = weights <= 0
    else:
        raise errors.ConnectionError(
            "Weights must be a number or an array of numbers.")
    if projection.post.conductance_based or projection.receptor_type == 'excitatory':
        if not all_positive:
            raise errors.ConnectionError(
                "Weights must be positive for conductance-based and/or excitatory synapses"
            )
    elif projection.post.conductance_based is False and projection.receptor_type == 'inhibitory':
        if not all_negative:
            raise errors.ConnectionError(
                "Weights must be negative for current-based, inhibitory synapses"
            )
    else:  # This should never happen.
        raise Exception("Can't check weight, conductance status unknown.")
コード例 #4
0
ファイル: connectors.py プロジェクト: agravier/pynn
 def connect(self, projection):
     """Connect-up a Projection."""
     idx     = numpy.argsort(self.conn_list[:, 1])
     self.targets    = numpy.unique(self.conn_list[:, 1]).astype(numpy.int)
     self.candidates = projection.pre.all_cells
     self.conn_list  = self.conn_list[idx]
     self.progressbar(len(self.targets))        
     count = 0
     left  = numpy.searchsorted(self.conn_list[:, 1], self.targets, 'left')
     right = numpy.searchsorted(self.conn_list[:, 1], self.targets, 'right')
     for tgt, l, r in zip(self.targets, left, right):
         sources = self.conn_list[l:r, 0].astype(numpy.int)
         weights = self.conn_list[l:r, 2]
         delays  = self.conn_list[l:r, 3]
     
         srcs     = projection.pre.all_cells[sources]
         try:
             srcs     = projection.pre.all_cells[sources]
         except IndexError:
             raise errors.ConnectionError("invalid sources index or indices")
         try:
             tgt    = projection.post.all_cells[tgt]
         except IndexError:
             raise errors.ConnectionError("invalid target index %d" %tgt)
         ## We need to exclude the non local cells. Fastidious, need maybe
         ## to use a convergent_connect method, instead of a divergent_connect one
         #idx     = eval(tests)
         #projection.connection_manager.connect(src, tgts[idx].tolist(), weights[idx], delays[idx])
         projection._convergent_connect(srcs.tolist(), tgt, weights, delays)
         self.progression(count, projection._simulator.state.mpi_rank)
         count += 1
コード例 #5
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))
コード例 #6
0
 def __init__(self,
              weights=0.0,
              delays=None,
              space=Space(),
              safe=True,
              verbose=False):
     self.weights = weights
     self.space = space
     self.safe = safe
     self.verbose = verbose
     min_delay = common.get_min_delay()
     if delays is None:
         self.delays = min_delay
     else:
         if core.is_listlike(delays):
             if min(delays) < min_delay:
                 raise errors.ConnectionError(
                     "smallest delay (%g) is smaller than minimum delay (%g)"
                     % (min(delays), min_delay))
         elif not (isinstance(delays, basestring)
                   or isinstance(delays, RandomDistribution)):
             if delays < min_delay:
                 raise errors.ConnectionError(
                     "delay (%g) is smaller than minimum delay (%g)" %
                     (delays, min_delay))
         self.delays = delays
コード例 #7
0
def check_weights(weights, projection):
    # if projection.post is an Assembly, some components might have cond-synapses, others curr, so need a more sophisticated check here
    synapse_sign = projection.receptor_type
    is_conductance = projection.post.conductance_based
    if isinstance(weights, numpy.ndarray):
        all_negative = (weights <= 0).all()
        all_positive = (weights >= 0).all()
        if not (all_negative or all_positive):
            raise errors.ConnectionError(
                "Weights must be either all positive or all negative")
    elif numpy.isreal(weights):
        all_positive = weights >= 0
        all_negative = weights < 0
    else:
        raise errors.ConnectionError(
            "Weights must be a number or an array of numbers.")
    if is_conductance or synapse_sign == 'excitatory':
        if not all_positive:
            raise errors.ConnectionError(
                "Weights must be positive for conductance-based and/or excitatory synapses"
            )
    elif is_conductance == False and synapse_sign == 'inhibitory':
        if not all_negative:
            raise errors.ConnectionError(
                "Weights must be negative for current-based, inhibitory synapses"
            )
    else:  # This should never happen.
        raise Exception("Can't check weight, conductance status unknown.")
コード例 #8
0
    def __init__(self,
                 presynaptic_neurons,
                 postsynaptic_neurons,
                 connector,
                 synapse_type=None,
                 source=None,
                 receptor_type=None,
                 space=Space(),
                 label=None):
        """
        Create a new projection, connecting the pre- and post-synaptic neurons.
        """
        if not hasattr(self, "_simulator"):
            errmsg = "`common.Projection` should not be instantiated directly. " \
                     "You should import Projection from a PyNN backend module, " \
                     "e.g. pyNN.nest or pyNN.neuron"
            raise Exception(errmsg)
        for prefix, pop in zip(("pre", "post"),
                               (presynaptic_neurons, postsynaptic_neurons)):
            if not isinstance(pop, (BasePopulation, Assembly)):
                raise errors.ConnectionError(
                    "%ssynaptic_neurons must be a Population, PopulationView or Assembly, not a %s"
                    % (prefix, type(pop)))

        if isinstance(postsynaptic_neurons, Assembly):
            if not postsynaptic_neurons._homogeneous_synapses:
                raise errors.ConnectionError(
                    'Projection to an Assembly object can be made only with homogeneous synapses types'
                )

        self.pre = presynaptic_neurons  # } these really
        self.source = source  # } should be
        self.post = postsynaptic_neurons  # } read-only
        if receptor_type == "default":
            receptor_type = None
        self.receptor_type = receptor_type or sorted(
            postsynaptic_neurons.receptor_types)[0]
        # TO FIX: if weights are negative, default should be the first inhibitory receptor type,
        #         not necessarily the first in alphabetical order.
        #         Should perhaps explicitly specify the default type(s)
        if self.receptor_type not in postsynaptic_neurons.receptor_types:
            valid_types = postsynaptic_neurons.receptor_types
            assert len(valid_types) > 0
            errmsg = "User gave receptor_types=%s, receptor_types must be one of: '%s'"
            raise errors.ConnectionError(
                errmsg % (self.receptor_type, "', '".join(valid_types)))
        self.label = label
        self.space = space
        self._connector = connector
        self.synapse_type = synapse_type or self._static_synapse_class()
        assert isinstance(self.synapse_type, models.BaseSynapseType), \
              "The synapse_type argument must be a models.BaseSynapseType object, not a %s" % type(synapse_type)
        if label is None:
            if self.pre.label and self.post.label:
                self.label = u"%s→%s" % (self.pre.label, self.post.label)
        self.initial_values = {}
        self.annotations = {}
        Projection._nProj += 1
コード例 #9
0
    def __init__(self, presynaptic_neurons, postsynaptic_neurons, connector,
                 synapse_type=None, source=None, receptor_type=None,
                 space=Space(), label=None):
        """
        Create a new projection, connecting the pre- and post-synaptic neurons.
        """
        if not hasattr(self, "_simulator"):
            errmsg = "`common.Projection` should not be instantiated directly. " \
                     "You should import Projection from a PyNN backend module, " \
                     "e.g. pyNN.nest or pyNN.neuron"
            raise Exception(errmsg)
        for prefix, pop in zip(("pre", "post"),
                               (presynaptic_neurons, postsynaptic_neurons)):
            if not isinstance(pop, (BasePopulation, Assembly)):
                raise errors.ConnectionError(
                    "%ssynaptic_neurons must be a Population, PopulationView or Assembly, not a %s" % (prefix, type(pop)))

        if isinstance(postsynaptic_neurons, Assembly):
            if not postsynaptic_neurons._homogeneous_synapses:
                raise errors.ConnectionError(
                    'Projection to an Assembly object can be made only with homogeneous synapses types')

        self.pre = presynaptic_neurons    # } these really
        self.source = source              # } should be
        self.post = postsynaptic_neurons  # } read-only
        self.label = label
        self.space = space
        if not isinstance(connector, Connector):
            raise TypeError(
                "The connector argument should be an instance of a subclass of Connector. "
                f"The argument provided was of type '{type(connector).__name__}'."
            )
        self._connector = connector

        self.synapse_type = synapse_type or self._static_synapse_class()
        if not isinstance(self.synapse_type, models.BaseSynapseType):
            raise TypeError(
                "The synapse_type argument should be an instance of a subclass of BaseSynapseType. "
                f"The argument provided was of type '{type(synapse_type).__name__}'"
            )

        self.receptor_type = receptor_type
        if self.receptor_type in ("default", None):
            self._guess_receptor_type()
        if self.receptor_type not in postsynaptic_neurons.receptor_types:
            valid_types = postsynaptic_neurons.receptor_types
            assert len(valid_types) > 0
            errmsg = "User gave receptor_types=%s, receptor_types must be one of: '%s'"
            raise errors.ConnectionError(errmsg % (self.receptor_type, "', '".join(valid_types)))

        if label is None:
            if self.pre.label and self.post.label:
                self.label = u"%s→%s" % (self.pre.label, self.post.label)
        self.initial_values = {}
        self.annotations = {}
        Projection._nProj += 1
コード例 #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))
コード例 #11
0
ファイル: __init__.py プロジェクト: agravier/pynn
    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))
コード例 #12
0
ファイル: __init__.py プロジェクト: markovg/PyNN
def check_delays(delays, projection):
    min_delay = projection._simulator.state.min_delay
    max_delay = projection._simulator.state.max_delay
    if isinstance(delays, numpy.ndarray):
        below_max = (delays <= max_delay).all()
        above_min = (delays >= min_delay).all()
        in_range = below_max and above_min
    elif numpy.isreal(delays):
        in_range = min_delay <= delays <= max_delay
    else:
        raise errors.ConnectionError("Delays must be a number or an array of numbers.")
    if not in_range:
        raise errors.ConnectionError("Delay (%s) is out of range [%s, %s]" % (delays, min_delay, max_delay))
コード例 #13
0
    def _convergent_connect(self, presynaptic_indices, postsynaptic_index,
                            **connection_parameters):
        """
        Connect a neuron to one or more other neurons with a static connection.

        `sources`  -- a 1D array of pre-synaptic cell IDs
        `target`   -- the ID of the post-synaptic cell.

        TO UPDATE
        """
        #logger.debug("Connecting to index %s from %s with %s" % (postsynaptic_index, presynaptic_indices, connection_parameters))
        presynaptic_cells = self.pre[presynaptic_indices].all_cells
        postsynaptic_cell = self.post[postsynaptic_index]
        assert len(presynaptic_cells) > 0, presynaptic_cells
        weights = connection_parameters.pop('weight')
        if self.receptor_type == 'inhibitory' and self.post.conductance_based:
            weights *= -1  # NEST wants negative values for inhibitory weights, even if these are conductances
        delays = connection_parameters.pop('delay')
        if postsynaptic_cell.celltype.standard_receptor_type:
            try:
                nest.ConvergentConnect(
                    presynaptic_cells.astype(int).tolist(),
                    [int(postsynaptic_cell)], listify(weights),
                    listify(delays), self.nest_synapse_model)
            except nest.NESTError, e:
                raise errors.ConnectionError(
                    "%s. presynaptic_cells=%s, postsynaptic_cell=%s, weights=%s, delays=%s, synapse model='%s'"
                    % (e, presynaptic_cells, postsynaptic_cell, weights,
                       delays, self.nest_synapse_model))
コード例 #14
0
    def _convergent_connect(self, presynaptic_indices, postsynaptic_index,
                            **connection_parameters):
        """
        Connect a neuron to one or more other neurons with a static connection.

        `presynaptic_cells`     -- a 1D array of pre-synaptic cell IDs
        `postsynaptic_cell`     -- the ID of the post-synaptic cell.
        `connection_parameters` -- each parameter should be either a
                                   1D array of the same length as `sources`, or
                                   a single value.
        """
        #logger.debug("Convergent connect. Weights=%s" % connection_parameters['weight'])
        postsynaptic_cell = self.post[postsynaptic_index]
        if not isinstance(
                postsynaptic_cell, int
        ) or postsynaptic_cell > simulator.state.gid_counter or postsynaptic_cell < 0:
            errmsg = "Invalid post-synaptic cell: %s (gid_counter=%d)" % (
                postsynaptic_cell, simulator.state.gid_counter)
            raise errors.ConnectionError(errmsg)
        for name, value in connection_parameters.items():
            if isinstance(value, (float, int)):
                connection_parameters[name] = repeat(value)
        assert postsynaptic_cell.local
        for pre_idx, values in core.ezip(presynaptic_indices,
                                         *connection_parameters.values()):
            parameters = dict(zip(connection_parameters.keys(), values))
            #logger.debug("Connecting neuron #%s to neuron #%s with synapse type %s, receptor type %s, parameters %s", pre_idx, postsynaptic_index, self.synapse_type, self.receptor_type, parameters)
            self._connections[postsynaptic_index][pre_idx].append(
                self.synapse_type.connection_type(self, pre_idx,
                                                  postsynaptic_index,
                                                  **parameters))
コード例 #15
0
ファイル: connectors.py プロジェクト: sbillaudelle/PyNN
    def connect(self, projection):
        """Connect-up a Projection."""
        logger.debug("conn_list (original) = \n%s", self.conn_list)
        if numpy.any(self.conn_list[:, 0] >= projection.pre.size):
            raise errors.ConnectionError("source index out of range")
        if (self.conn_list.shape[1] < 3 or self.conn_list.shape[1] > 4
                or (self.conn_list.shape[1] == 3
                    and projection.synapse_type.has_parameter('delay'))):
            raise errors.ConnectionError(
                "incompatible number of columns for connection list requires "
                "4 (3 for synapse type without delay)")
        # need to do some profiling, to figure out the best way to do this:
        #  - order of sorting/filtering by local
        #  - use numpy.unique, or just do in1d(self.conn_list)?
        idx = numpy.argsort(self.conn_list[:, 1])
        targets = numpy.unique(self.conn_list[:, 1]).astype(numpy.int)
        local = numpy.in1d(
            targets,
            numpy.arange(projection.post.size)[projection.post._mask_local],
            assume_unique=True)
        local_targets = targets[local]
        self.conn_list = self.conn_list[idx]
        left = numpy.searchsorted(self.conn_list[:, 1], local_targets, 'left')
        right = numpy.searchsorted(self.conn_list[:, 1], local_targets,
                                   'right')
        logger.debug("idx = %s", idx)
        logger.debug("targets = %s", targets)
        logger.debug("local_targets = %s", local_targets)
        logger.debug("conn_list (sorted by target) = \n%s", self.conn_list)
        logger.debug("left = %s", left)
        logger.debug("right = %s", right)

        schema = projection.synapse_type.get_schema()
        for tgt, l, r in zip(local_targets, left, right):
            sources = self.conn_list[l:r, 0].astype(numpy.int)
            param_dict = {'weight': self.conn_list[l:r, 2]}
            if self.conn_list.shape[1] == 4:
                param_dict['delay'] = self.conn_list[l:r, 3]
            connection_parameters = ParameterSpace(param_dict,
                                                   schema=schema,
                                                   shape=(r - l, ))
            if isinstance(projection.synapse_type, StandardSynapseType):
                connection_parameters = projection.synapse_type.translate(
                    connection_parameters)
            connection_parameters.evaluate()
            projection._convergent_connect(sources, tgt,
                                           **connection_parameters)
コード例 #16
0
 def check(self, delay):
     all_negative = (delay <= self.max_delay).all()
     all_positive = (delay >= self.min_delay).all(
     )  # If the delay is too small , we have to throw an error
     if not (all_negative and all_positive):
         raise errors.ConnectionError(
             "delay (%s) is out of range [%s,%s]" %
             (delay, common.get_min_delay(), common.get_max_delay()))
     return delay
コード例 #17
0
ファイル: __init__.py プロジェクト: agravier/pynn
    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))
コード例 #18
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 errors.ConnectionError(errmsg)
        if not core.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 errors.ConnectionError("Invalid target ID: %s" % target)

        assert len(targets) == len(weights) == len(delays), "%s %s %s" % (
            len(targets), len(weights), len(delays))
        self._resolve_synapse_type()
        for target, weight, delay in zip(targets, weights, delays):
            if target.local:
                if "." in self.synapse_type:
                    section, synapse_type = self.synapse_type.split(".")
                    synapse_object = getattr(getattr(target._cell, section),
                                             synapse_type)
                else:
                    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))
コード例 #19
0
ファイル: connectors.py プロジェクト: agravier/pynn
 def check(self, delay):
     min_delay = self.kernel.min_delay
     max_delay = self.kernel.max_delay
     all_negative = (delay <= max_delay).all()
     all_positive = (delay >= min_delay).all(
     )  # If the delay is too small , we have to throw an error
     if not (all_negative and all_positive):
         raise errors.ConnectionError("delay (%s) is out of range [%s,%s]" %
                                      (delay, min_delay, max_delay))
     return delay
コード例 #20
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) or target > state.gid_counter or target < 0:
            errmsg = "Invalid target ID: %s (gid_counter=%d)" % (
                target, state.gid_counter)
            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 target.local:
            for source, weight, delay in zip(sources, weights, delays):
                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))
コード例 #21
0
ファイル: connectors.py プロジェクト: sanjayankur31/PyNN
 def connect(self, projection):
     if (projection.pre != self.reference_projection.pre or
             projection.post != self.reference_projection.post):
         raise errors.ConnectionError("Pre and post populations must match between reference ({0}"
                                      "  and {1}) and clone projections ({2} and {3}) for "
                                      "CloneConnector"
                                      .format(self.reference_projection.pre,
                                              self.reference_projection.post,
                                              projection.pre, projection.post))
     connection_map = LazyArray(~np.isnan(self.reference_projection.get(['weight'], 'array',
                                                                           gather='all')[0]))
     self._connect_with_map(projection, connection_map)
コード例 #22
0
ファイル: connectors.py プロジェクト: wau/PyNN
    def connect(self, projection):
        """Connect-up a Projection."""
        logger.debug("conn_list (original) = \n%s", self.conn_list)
        synapse_parameter_names = projection.synapse_type.get_parameter_names()
        for name in self.column_names:
            if name not in synapse_parameter_names:
                raise ValueError(
                    "%s is not a valid parameter for %s" %
                    (name, projection.synapse_type.__class__.__name__))
        if self.conn_list.size == 0:
            return
        if numpy.any(self.conn_list[:, 0] >= projection.pre.size):
            raise errors.ConnectionError("source index out of range")
        # need to do some profiling, to figure out the best way to do this:
        #  - order of sorting/filtering by local
        #  - use numpy.unique, or just do in1d(self.conn_list)?
        idx = numpy.argsort(self.conn_list[:, 1])
        targets = numpy.unique(self.conn_list[:, 1]).astype(numpy.int)
        local = numpy.in1d(
            targets,
            numpy.arange(projection.post.size)[projection.post._mask_local],
            assume_unique=True)
        local_targets = targets[local]
        self.conn_list = self.conn_list[idx]
        left = numpy.searchsorted(self.conn_list[:, 1], local_targets, 'left')
        right = numpy.searchsorted(self.conn_list[:, 1], local_targets,
                                   'right')
        logger.debug("idx = %s", idx)
        logger.debug("targets = %s", targets)
        logger.debug("local_targets = %s", local_targets)
        logger.debug("conn_list (sorted by target) = \n%s", self.conn_list)
        logger.debug("left = %s", left)
        logger.debug("right = %s", right)

        for tgt, l, r in zip(local_targets, left, right):
            sources = self.conn_list[l:r, 0].astype(numpy.int)
            connection_parameters = deepcopy(
                projection.synapse_type.parameter_space)

            connection_parameters.shape = (r - l, )
            for col, name in enumerate(self.column_names, 2):
                connection_parameters.update(
                    **{name: self.conn_list[l:r, col]})
            if isinstance(projection.synapse_type, StandardSynapseType):
                connection_parameters = projection.synapse_type.translate(
                    connection_parameters)
            connection_parameters.evaluate()
            projection._convergent_connect(sources, tgt,
                                           **connection_parameters)
コード例 #23
0
    def __init__(self,
                 presynaptic_neurons,
                 postsynaptic_neurons,
                 method,
                 source=None,
                 target=None,
                 synapse_dynamics=None,
                 label=None,
                 rng=None):
        """
        presynaptic_neurons and postsynaptic_neurons - Population, PopulationView
                                                       or Assembly objects.

        source - string specifying which attribute of the presynaptic cell
                 signals action potentials. This is only needed for
                 multicompartmental cells with branching axons or
                 dendrodendriticsynapses. All standard cells have a single
                 source, and this is the default.

        target - string specifying which synapse on the postsynaptic cell to
                 connect to. For standard cells, this can be 'excitatory' or
                 'inhibitory'. For non-standard cells, it could be 'NMDA', etc.
                 If target is not given, the default values of 'excitatory' is
                 used.

        method - a Connector object, encapsulating the algorithm to use for
                 connecting the neurons.

        synapse_dynamics - a `standardmodels.SynapseDynamics` object specifying
                 which synaptic plasticity mechanisms to use.

        rng - specify an RNG object to be used by the Connector.
        """
        for prefix, pop in zip(("pre", "post"),
                               (presynaptic_neurons, postsynaptic_neurons)):
            if not isinstance(pop, (BasePopulation, Assembly)):
                raise errors.ConnectionError(
                    "%ssynaptic_neurons must be a Population, PopulationView or Assembly, not a %s"
                    % (prefix, type(pop)))

        if isinstance(postsynaptic_neurons, Assembly):
            if not postsynaptic_neurons._homogeneous_synapses:
                raise Exception(
                    'Projection to an Assembly object can be made only with homogeneous synapses types'
                )

        self.pre = presynaptic_neurons  #  } these really
        self.source = source  #  } should be
        self.post = postsynaptic_neurons  #  } read-only
        self.target = target  #  }
        self.label = label
        if isinstance(rng, random.AbstractRNG):
            self.rng = rng
        elif rng is None:
            self.rng = random.NumpyRNG(seed=151985012)
        else:
            raise Exception(
                "rng must be either None, or a subclass of pyNN.random.AbstractRNG"
            )
        self._method = method
        self.synapse_dynamics = synapse_dynamics
        #self.connection = None # access individual connections. To be defined by child, simulator-specific classes
        self.weights = []
        if label is None:
            if self.pre.label and self.post.label:
                self.label = "%s→%s" % (self.pre.label, self.post.label)
        if self.synapse_dynamics:
            assert isinstance(self.synapse_dynamics, models.BaseSynapseDynamics), \
              "The synapse_dynamics argument, if specified, must be a models.BaseSynapseDynamics object, not a %s" % type(synapse_dynamics)
コード例 #24
0
    def _convergent_connect(self, presynaptic_indices, postsynaptic_index,
                            **connection_parameters):
        """
        Connect a neuron to one or more other neurons with a static connection.

        `sources`  -- a 1D array of pre-synaptic cell IDs
        `target`   -- the ID of the post-synaptic cell.

        TO UPDATE
        """
        #logger.debug("Connecting to index %s from %s with %s" % (postsynaptic_index, presynaptic_indices, connection_parameters))
        presynaptic_cells = self.pre.all_cells[presynaptic_indices]
        postsynaptic_cell = self.post[postsynaptic_index]
        assert presynaptic_cells.size == presynaptic_indices.size
        assert len(presynaptic_cells) > 0, presynaptic_cells

        weights = connection_parameters.pop('weight')
        if self.receptor_type == 'inhibitory' and self.post.conductance_based:
            weights *= -1  # NEST wants negative values for inhibitory weights, even if these are conductances
        if hasattr(self.post, "celltype") and hasattr(
                self.post.celltype,
                "receptor_scale"):  # this is a bit of a hack
            weights *= self.post.celltype.receptor_scale  # needed for the Izhikevich model
        delays = connection_parameters.pop('delay')

        # Create connections, with weights and delays
        # Setting other connection parameters is done afterwards
        if postsynaptic_cell.celltype.standard_receptor_type:
            try:
                if not numpy.isscalar(weights):
                    weights = numpy.array([weights])
                if not numpy.isscalar(delays):
                    delays = numpy.array([delays])
                syn_dict = {
                    'model': self.nest_synapse_model,
                    'weight': weights,
                    'delay': delays,
                    'synapse_label': self.nest_synapse_label,
                }

                if 'tsodyks' in self.nest_synapse_model:
                    if self.receptor_type == 'inhibitory':
                        param_name = self.post.local_cells[
                            0].celltype.translations['tau_syn_I'][
                                'translated_name']
                    elif self.receptor_type == 'excitatory':
                        param_name = self.post.local_cells[
                            0].celltype.translations['tau_syn_E'][
                                'translated_name']
                    else:
                        raise NotImplementedError()
                    syn_dict.update({
                        'tau_psc':
                        numpy.array([[
                            nest.GetStatus([postsynaptic_cell], param_name)[0]
                        ] * len(presynaptic_cells.astype(int).tolist())])
                    })

                nest.Connect(
                    presynaptic_cells.astype(int).tolist(),
                    [int(postsynaptic_cell)], 'all_to_all', syn_dict)
            except nest.kernel.NESTError as e:
                errmsg = "%s. presynaptic_cells=%s, postsynaptic_cell=%s, weights=%s, delays=%s, synapse model='%s'" % (
                    e, presynaptic_cells, postsynaptic_cell, weights, delays,
                    self.nest_synapse_model)
                raise errors.ConnectionError(errmsg)
        else:
            receptor_type = postsynaptic_cell.celltype.get_receptor_type(
                self.receptor_type)
            if numpy.isscalar(weights):
                weights = repeat(weights)
            if numpy.isscalar(delays):
                delays = repeat(delays)
            for pre, w, d in zip(presynaptic_cells, weights, delays):

                syn_dict = {
                    'weight': w,
                    'delay': d,
                    'receptor_type': receptor_type,
                    'model': self.nest_synapse_model,
                    'synapse_label': self.nest_synapse_label
                }

                if 'tsodyks' in self.nest_synapse_model:
                    syn_dict.update({
                        'tau_psc':
                        numpy.array([[
                            nest.GetStatus([postsynaptic_cell], param_name)[0]
                        ] * len(presynaptic_cells.astype(int).tolist())])
                    })

                nest.Connect([pre], [postsynaptic_cell], 'one_to_one',
                             syn_dict)

        # Book-keeping
        self._connections = None  # reset the caching of the connection list, since this will have to be recalculated
        self._sources.extend(presynaptic_cells)

        # Clean the connection parameters
        connection_parameters.pop(
            'tau_minus',
            None)  # TODO: set tau_minus on the post-synaptic cells
        connection_parameters.pop('dendritic_delay_fraction', None)
        connection_parameters.pop('w_min_always_zero_in_NEST', None)

        # We need to distinguish between common synapse parameters and local ones
        # We just get the parameters of the first connection (is there an easier way?)
        if self._common_synapse_property_names is None:
            self._identify_common_synapse_properties()

        # Set connection parameters other than weight and delay
        if connection_parameters:
            #logger.debug(connection_parameters)
            sort_indices = numpy.argsort(presynaptic_cells)
            connections = nest.GetConnections(
                source=numpy.unique(presynaptic_cells.astype(int)).tolist(),
                target=[int(postsynaptic_cell)],
                synapse_model=self.nest_synapse_model,
                synapse_label=self.nest_synapse_label)
            for name, value in connection_parameters.items():
                if name not in self._common_synapse_property_names:
                    value = make_sli_compatible(value)
                    #logger.debug("Setting %s=%s for connections %s" % (name, value, connections))
                    if isinstance(value, numpy.ndarray):
                        # the str() is to work around a bug handling unicode names in SetStatus in NEST 2.4.1 when using Python 2
                        nest.SetStatus(connections, str(name),
                                       value[sort_indices].tolist())
                    else:
                        nest.SetStatus(connections, str(name), value)
                else:
                    self._set_common_synapse_property(name, value)
コード例 #25
0
ファイル: projections.py プロジェクト: sanjayankur31/PyNN
    def _convergent_connect(self, presynaptic_indices, postsynaptic_index,
                            **connection_parameters):
        """
        Connect a neuron to one or more other neurons with a static connection.

        `presynaptic_indices` - 1D array of presynaptic indices
        `postsynaptic_index` - integer - the index of the postsynaptic neuron
        `connection_parameters` - dict whose keys are native NEST parameter names. Values may be scalars or arrays.
        """
        # Clean the connection parameters by removing parameters that are
        # used by PyNN but should not be passed to NEST
        connection_parameters.pop(
            'tau_minus',
            None)  # TODO: set tau_minus on the post-synaptic cells
        connection_parameters.pop('dendritic_delay_fraction', None)
        connection_parameters.pop('w_min_always_zero_in_NEST', None)

        syn_dict = {
            'synapse_model': self.nest_synapse_model,
            'synapse_label': self.nest_synapse_label,
        }

        # Weights require some special handling
        if self.receptor_type == 'inhibitory' and self.post.conductance_based:
            connection_parameters[
                'weight'] *= -1  # NEST wants negative values for inhibitory weights, even if these are conductances
            if "stdp" in self.nest_synapse_model:
                syn_dict[
                    "Wmax"] = -1.2345e6  # just some very large negative value to avoid
                # NEST complaining about weight and Wmax having different signs
                # (see https://github.com/NeuralEnsemble/PyNN/issues/636)
                # Will be overwritten below.
                connection_parameters["Wmax"] *= -1
        if hasattr(self.post, "celltype") and hasattr(
                self.post.celltype,
                "receptor_scale"):  # this is a bit of a hack
            connection_parameters[
                'weight'] *= self.post.celltype.receptor_scale  # needed for the Izhikevich model

        # Prepare connections. NodeCollections can't have repeated values, so for some
        # connector types we need to split the presynaptic cells into groups that
        # don't have such repeats.

        # note that NEST needs sorted indices
        sort_indices = presynaptic_indices.argsort()
        presynaptic_indices = presynaptic_indices[sort_indices]
        for name, value in connection_parameters.items():
            if isinstance(value, np.ndarray):
                connection_parameters[name] = value[sort_indices]

        try:
            presynaptic_cell_groups = [
                self.pre.node_collection[presynaptic_indices]
            ]
            connection_parameter_groups = [connection_parameters]
        except ValueError as err:
            if "All node IDs in a NodeCollection have to be unique" in str(
                    err):
                presynaptic_index_groups, connection_parameter_groups = \
                    split_array_to_avoid_repeats(presynaptic_indices, **connection_parameters)
                presynaptic_cell_groups = [
                    self.pre.node_collection[i]
                    for i in presynaptic_index_groups
                ]
            else:
                raise
        postsynaptic_cell = self.post[postsynaptic_index]

        # Create connections and set parameters
        for presynaptic_cells, connection_parameter_group in zip(
                presynaptic_cell_groups, connection_parameter_groups):
            self._sources.update(presynaptic_cells.tolist())
            try:
                weights = connection_parameter_group.pop('weight')
                delays = connection_parameter_group.pop('delay')
                # nest.Connect expects a 2D array
                if not np.isscalar(weights):
                    weights = np.array([weights])
                if not np.isscalar(delays):
                    delays = np.array([delays])
                syn_dict.update({'weight': weights, 'delay': delays})

                if postsynaptic_cell.celltype.standard_receptor_type:
                    # For Tsodyks-Markram synapses models we set the "tau_psc" parameter to match
                    # the relevant "tau_syn" parameter from the post-synaptic neuron.
                    if 'tsodyks' in self.nest_synapse_model:
                        if self.receptor_type == 'inhibitory':
                            param_name = postsynaptic_cell.celltype.translations[
                                'tau_syn_I']['translated_name']
                        elif self.receptor_type == 'excitatory':
                            param_name = postsynaptic_cell.celltype.translations[
                                'tau_syn_E']['translated_name']
                        else:
                            raise NotImplementedError()
                        syn_dict["tau_psc"] = nest.GetStatus(
                            postsynaptic_cell.node_collection, param_name)[0]
                else:
                    syn_dict.update({
                        "receptor_type":
                        postsynaptic_cell.celltype.get_receptor_type(
                            self.receptor_type)
                    })

                # For parameters other than weight and delay, we need to know if they are "common"
                # parameters (the same for all synapses) or "local" (different synapses can have
                # different values), as this affects how they are set.
                #
                # To introspect which parameters are common, we need an existing connection, so
                # the first time we create connections we pass just the weight and delay, and set
                # the other parameters later. We then get the list of common parameters and cache
                # it so that in subsequent Connect() calls we can pass all of the local
                # (non-common) parameters.

                if self._common_synapse_property_names is None:
                    nest.Connect(presynaptic_cells,
                                 postsynaptic_cell.node_collection,
                                 'all_to_all', syn_dict)
                    self._identify_common_synapse_properties()

                    # Retrieve connections so that we can set additional
                    # parameters using nest.SetStatus
                    connections = nest.GetConnections(
                        source=presynaptic_cells,
                        target=postsynaptic_cell.node_collection,
                        synapse_model=self.nest_synapse_model,
                        synapse_label=self.nest_synapse_label)
                    for name, value in connection_parameter_group.items():
                        if name not in self._common_synapse_property_names:
                            value = make_sli_compatible(value)
                            if isinstance(value, np.ndarray):
                                nest.SetStatus(connections, name,
                                               value.tolist())
                            else:
                                nest.SetStatus(connections, name, value)
                        else:
                            self._set_common_synapse_property(name, value)
                else:
                    # Since we know which parameters are common, we can set the non-common
                    # parameters directly in the nest.Connect call
                    syn_dict = self._update_syn_params(
                        syn_dict, connection_parameter_group)
                    nest.Connect(presynaptic_cells,
                                 postsynaptic_cell.node_collection,
                                 'all_to_all', syn_dict)
                    # and then set the common parameters
                    for name, value in connection_parameter_group.items():
                        if name in self._common_synapse_property_names:
                            self._set_common_synapse_property(name, value)

            except nest.kernel.NESTError as e:
                errmsg = "%s. presynaptic_cells=%s, postsynaptic_cell=%s, weights=%s, delays=%s, synapse model='%s'" % (
                    e, presynaptic_cells, postsynaptic_cell, weights, delays,
                    self.nest_synapse_model)
                raise errors.ConnectionError(errmsg)

        # Reset the caching of the connection list, since this will have to be recalculated
        self._connections = None
        self._simulator.state.stale_connection_cache = True