コード例 #1
0
ファイル: base.py プロジェクト: nsk6999/pype9
 def __init__(self, nineml_model, build_mode='lazy', **kwargs):
     if not isinstance(nineml_model, ComponentArray9ML):
         raise Pype9RuntimeError(
             "Expected a component array, found {}".format(nineml_model))
     self._nineml = nineml_model
     dynamics_properties = nineml_model.dynamics_properties
     dynamics = dynamics_properties.component_class
     celltype = self.PyNNCellWrapperMetaClass(
         component_class=dynamics,
         default_properties=dynamics_properties,
         initial_state=list(dynamics_properties.initial_values),
         initial_regime=dynamics_properties.initial_regime,
         build_mode=build_mode, **kwargs)
     if build_mode != 'build_only':
         rng = self.Simulation.active().properties_rng
         cellparams = dict(
             (p.name, get_pyNN_value(p, self.UnitHandler, rng))
             for p in dynamics_properties.properties)
         initial_values = dict(
             (i.name, get_pyNN_value(i, self.UnitHandler, rng))
             for i in dynamics_properties.initial_values)
         initial_values['_regime'] = celltype.model.regime_index(
             dynamics_properties.initial_regime)
         # NB: Simulator-specific derived classes extend the corresponding
         # PyNN population class
         self.PyNNPopulationClass.__init__(
             self, nineml_model.size, celltype, cellparams=cellparams,
             initial_values=initial_values,
             label=nineml_model.name)
         self._inputs = {}
     self._t_stop = None
     self.Simulation.active().register_array(self)
コード例 #2
0
 def connections(self):
     if not self.has_been_sampled():
         raise Pype9RuntimeError(
             "Connections have not been generated for PyNNConnectivity "
             "object (they are only generated during network construction "
             "for efficiency")
     raise NotImplementedError(
         "Need to work out connection list from connection map")
コード例 #3
0
ファイル: base.py プロジェクト: nsk6999/pype9
 def __init__(self, nineml_model, build_mode='lazy', **kwargs):
     if isinstance(nineml_model, basestring):
         nineml_model = nineml.read(nineml_model).as_network(
             name=os.path.splitext(os.path.basename(nineml_model))[0])
     elif isinstance(nineml_model, Document):
         if nineml_model.url is not None:
             name = os.path.splitext(os.path.basename(nineml_model.url))[0]
         else:
             name = "Anonymous"
         nineml_model = nineml_model.as_network(name=name)
     self._nineml = nineml_model.clone()
     # Get RNG for random distribution values and connectivity
     rng = self.Simulation.active().properties_rng
     if build_mode != 'build_only':
         self.nineml.resample_connectivity(
             connectivity_class=self.ConnectivityClass, rng=rng)
     (flat_comp_arrays, flat_conn_groups,
      flat_selections) = self._flatten_to_arrays_and_conns(self._nineml)
     self._component_arrays = {}
     # Build the PyNN populations
     # Add build args to distinguish models built for this network as
     # opposed to other networks
     build_url = kwargs.pop('build_url', nineml_model.url)
     build_version = nineml_model.name + kwargs.pop('build_version', '')
     for name, comp_array in flat_comp_arrays.items():
         self._component_arrays[name] = self.ComponentArrayClass(
             comp_array, build_mode=build_mode,
             build_url=build_url, build_version=build_version, **kwargs)
     self._selections = {}
     # Build the PyNN Selections
     for selection in flat_selections.values():
         # TODO: Assumes that selections are only concatenations (which is
         #       true for 9MLv1.0 but not v2.0)
         self._selections[selection.name] = self.SelectionClass(
             selection, *[self.component_array(p.name)
                          for p in selection.populations])
     if build_mode != 'build_only':
         # Set the connectivity objects of the projections to the
         # PyNNConnectivity class
         if self.nineml.connectivity_has_been_sampled():
             raise Pype9RuntimeError(
                 "Connections have already been sampled, please reset them"
                 " using 'resample_connectivity' before constructing "
                 "network")
         self._connection_groups = {}
         for name, conn_group in flat_conn_groups.items():
             try:
                 source = self._component_arrays[conn_group.source.name]
             except KeyError:
                 source = self._selections[conn_group.source.name]
             try:
                 destination = self._component_arrays[
                     conn_group.destination.name]
             except KeyError:
                 destination = self._selections[conn_group.destination.name]
             self._connection_groups[name] = self.ConnectionGroupClass(
                 conn_group, source=source, destination=destination)
         self._finalise_construction()
コード例 #4
0
    def path_to_utility(self,
                        utility_name,
                        env_var='',
                        **kwargs):  # @UnusedVariable @IgnorePep8
        """
        Returns the full path to an executable by searching the "PATH"
        environment variable

        Parameters
        ----------
        utility_name : str
            Name of executable to search the execution path
        env_var : str
            Name of a environment variable to lookup first before searching
            path
        default : str | None
            The default value to assign to the path if it cannot be found.

        Returns
        -------
        utility_path : str
            Full path to executable
        """
        if kwargs and list(kwargs) != ['default']:
            raise Pype9RuntimeError(
                "Should only provide 'default' as kwarg to path_to_utility "
                "provided ({})".format(kwargs))
        try:
            utility_path = os.environ[env_var]
        except KeyError:
            if platform.system() == 'Windows':
                utility_name += '.exe'
            # Get the system path
            system_path = os.environ['PATH'].split(os.pathsep)
            # Append NEST_INSTALL_DIR/NRNHOME if present
            system_path.extend(self.simulator_specific_paths())
            # Check the system path for the command
            utility_path = None
            for dr in system_path:
                path = join(dr, utility_name)
                if os.path.exists(path):
                    utility_path = path
                    break
            if not utility_path:
                try:
                    utility_path = kwargs['default']
                except KeyError:
                    raise Pype9CommandNotFoundError(
                        "Could not find executable '{}' on the system path "
                        "'{}'".format(utility_name, ':'.join(system_path)))
        else:
            if not os.path.exists(utility_path):
                raise Pype9CommandNotFoundError(
                    "Could not find executable '{}' at path '{}' provided by "
                    "'{}' environment variable".format(utility_name, env_var))
        return utility_path
コード例 #5
0
 def _check_connection_properties(self, port_name, properties):
     props_dict = dict((p.name, p) for p in properties)
     try:
         param_set = self._nineml.component_class.connection_parameter_set(
             port_name)
     except NineMLNameError:
         return  # No parameter set, so no need to check
     params_dict = dict((p.name, p) for p in param_set.parameters)
     if set(props_dict.keys()) != set(params_dict.keys()):
         raise Pype9RuntimeError(
             "Mismatch between provided property and parameter names:"
             "\nParameters: '{}'\nProperties: '{}'"
             .format("', '".join(iter(params_dict.keys())),
                     "', '".join(iter(props_dict.keys()))))
     for prop in properties:
         if params_dict[prop.name].dimension != prop.units.dimension:
             raise Pype9RuntimeError(
                 "Dimension of property '{}' ({}) does not match that of "
                 "the corresponding parameter ({})"
                 .format(prop.name, prop.units.dimension,
                         params_dict[prop.name].dimension))
コード例 #6
0
ファイル: with_synapses.py プロジェクト: nsk6999/pype9
 def wrap(cls,
          dynamics_properties,
          synapses_properties=[],
          connection_property_sets=[]):
     if isinstance(dynamics_properties, MultiDynamicsProperties):
         wrapped_cls = MultiDynamicsWithSynapsesProperties
     elif isinstance(dynamics_properties, DynamicsProperties):
         wrapped_cls = DynamicsWithSynapsesProperties
     else:
         raise Pype9RuntimeError(
             "Cannot wrap '{}' class with WithSynapses, only Dynamics and "
             "MultiDynamics".format(type(dynamics_properties)))
     return wrapped_cls(dynamics_properties.name, dynamics_properties,
                        synapses_properties, connection_property_sets)
コード例 #7
0
ファイル: with_synapses.py プロジェクト: nsk6999/pype9
 def __init__(self, name, dynamics, synapses, connection_parameter_sets):
     assert isinstance(dynamics, (Dynamics, MultiDynamics))
     # Initialise Dynamics/MultiDynamics base classes
     self._name = validate_identifier(name)
     self._dynamics = dynamics
     self.add(*synapses)
     self.add(*connection_parameter_sets)
     for conn_param in self.all_connection_parameters():
         try:
             dyn_param = self._dynamics.parameter(conn_param.name)
             if conn_param.dimension != dyn_param.dimension:
                 raise Pype9RuntimeError(
                     "Inconsistent dimensions between connection parameter"
                     " '{}' ({}) and parameter of the same name ({})".
                     format(conn_param.name, conn_param.dimension,
                            dyn_param.dimension))
         except NineMLNameError:
             raise Pype9RuntimeError(
                 "Connection parameter '{}' does not refer to a parameter "
                 "in the base MultiDynamics class ('{}')".format(
                     conn_param,
                     "', '".join(sp.name
                                 for sp in self._dynamics.parameters)))
     self._dimension_resolver = None
コード例 #8
0
ファイル: with_synapses.py プロジェクト: nsk6999/pype9
 def wrap(cls, dynamics, synapses=None, connection_parameter_sets=None):
     if synapses is None:
         synapses = []
     if connection_parameter_sets is None:
         connection_parameter_sets = []
     if isinstance(dynamics, MultiDynamics):
         wrapped_cls = MultiDynamicsWithSynapses
     elif isinstance(dynamics, Dynamics):
         wrapped_cls = DynamicsWithSynapses
     else:
         raise Pype9RuntimeError(
             "Cannot wrap '{}' class with WithSynapses, only Dynamics and "
             "MultiDynamics".format(type(dynamics)))
     name = dynamics.name
     dynamics = dynamics.clone()
     dynamics.name = name + '__sans_synapses'
     return wrapped_cls(name, dynamics, synapses, connection_parameter_sets)
コード例 #9
0
ファイル: base.py プロジェクト: nsk6999/pype9
 def synapse(self, name):
     try:
         synapses = set(
             ca.nineml.dynamics_properties.synapse_properties(name)
             for ca in self.component_arrays)
     except NineMLNameError:
         raise NineMLNameError(
             "Could not return synapse '{}' because it is missing from "
             "one or more of the component arrays in '{}' Selection"
             .format(name, self.name))
     if len(synapses) > 1:
         raise Pype9RuntimeError(
             "'{}' varies ({}) between component arrays in '{}' Selection"
             .format(name, ', '.join(str(s) for s in synapses), self.name))
     try:
         return next(iter(synapses))  # Return the only synapse
     except:
         raise
コード例 #10
0
ファイル: base.py プロジェクト: nsk6999/pype9
 def __init__(self, nineml_model, source, destination):
     rng = self.Simulation.active().properties_rng
     if not isinstance(nineml_model, EventConnectionGroup9ML):
         raise Pype9RuntimeError(
             "Expected a connection group model, found {}"
             .format(nineml_model))
     try:
         (synapse, conns) = destination.synapse(nineml_model.name)
         if conns is not None:
             raise NotImplementedError(
                 "Nonlinear synapses, as used in '{}' are not currently "
                 "supported".format(nineml_model.name))
         if synapse.num_local_properties == 1:
             # Get the only local property that varies with the synapse
             # (typically the synaptic weight but does not have to be)
             weight = get_pyNN_value(next(synapse.local_properties),
                                     self.UnitHandler, rng)
         elif not synapse.num_local_properties:
             weight = 0.0
         else:
             raise NotImplementedError(
                 "Currently only supports one property that varies with "
                 "each synapse")
     except NineMLNameError:
         # FIXME: Should refactor "WithSynapses" code to "CellAndSynapses"
         #        class which inherits most of its functionality from
         #        MultiDynamics to ensure that every connection has a
         #        "synapse" even if it is just a simple port exposure
         # Synapse dynamics properties didn't have any properties that vary
         # between synapses so wasn't included
         weight = 0.0
     self._nineml = nineml_model
     delay = get_pyNN_value(nineml_model.delay, self.UnitHandler, rng)
     # FIXME: Ignores send_port, assumes there is only one...
     # NB: Simulator-specific derived classes extend the corresponding
     # PyNN population class
     self.PyNNProjectionClass.__init__(
         self,
         presynaptic_population=source,
         postsynaptic_population=destination,
         connector=nineml_model.connectivity,
         synapse_type=self.SynapseClass(weight=weight, delay=delay),
         receptor_type=nineml_model.destination_port,
         label=nineml_model.name)
コード例 #11
0
ファイル: base.py プロジェクト: nsk6999/pype9
 def __setattr__(self, varname, val):
     # Capture attributes ending with '_init' (the convention PyNN uses to
     # specify initial conditions of state variables) and save them in
     # initial states
     if varname == '_regime_init':
         object.__setattr__(self, '_regime_index', val)
     elif (varname.endswith('_init')
           and varname[:-5] in self.component_class.state_variable_names):
         if varname in chain(self.component_class.state_variable_names,
                             self.component_class.parameter_names):
             raise Pype9RuntimeError(
                 "Ambiguous variable '{}' can either be the initial state "
                 "of '{}' or a parameter/state-variable".format(
                     varname, varname[:-5]))
         self._initial_states[varname[:-5]] = val
     elif varname in ('record_times', 'recording_time'):
         # PyNN needs to be able to set 'record_times' and 'recording_time'
         # to record state variables
         object.__setattr__(self, varname, val)
     else:
         super(Cell, self).__setattr__(varname, val)
コード例 #12
0
 def from_pq_quantity(cls, qty):
     if isinstance(qty, Quantity):
         return qty  # If already a 9ML quantity
     elif isinstance(qty, (int, float)):
         units = un.unitless
     elif isinstance(qty, pq.Quantity):
         unit_name = str(qty.units).split()[1].replace(
             '/', '_per_').replace('**', '').replace('*', '_').replace(
                 '(', '').replace(')', '')
         if unit_name.startswith('_per_'):
             unit_name = unit_name[1:]  # strip leading underscore
         powers = dict(
             (cls._pq_si_to_dim[type(u)], p)
             for u, p in qty.units.simplified._dimensionality.items())
         dimension = un.Dimension(unit_name + 'Dimension', **powers)
         units = un.Unit(unit_name, dimension=dimension,
                         power=int(log10(float(qty.units.simplified))))
     else:
         raise Pype9RuntimeError(
             "Cannot '{}' to nineml.Quantity (can only convert "
             "quantities.Quantity and numeric objects)"
             .format(qty))
     return Quantity(float(qty), units)
コード例 #13
0
ファイル: base.py プロジェクト: nsk6999/pype9
    def _flatten_to_arrays_and_conns(cls, network_model):
        """
        Convert populations and projections into component arrays and
        connection groups
        """
        component_arrays = {}
        connection_groups = {}
        # Create flattened component with all synapses combined with the post-
        # synaptic cell dynamics using MultiDynamics
        for pop in network_model.populations:
            # Get all the projections that project to/from the given population
            receiving = [p for p in network_model.projections
                         if (pop == p.post or
                             (p.post.nineml_type == 'Selection' and
                              pop in p.post.populations))]
            sending = [p for p in network_model.projections
                       if (pop == p.pre or
                           (p.pre.nineml_type == 'Selection' and
                            pop in p.pre.populations))]
            # Create a dictionary to hold the cell dynamics and any synapse
            # dynamics that can be flattened into the cell dynamics
            # (i.e. linear ones).
            sub_components = {cls.CELL_COMP_NAME: pop.cell}
            # All port connections between post-synaptic cell and linear
            # synapses and port exposures to pre-synaptic cell
            internal_conns = []
            exposures = []

            def add_exposures(exposures_to_add):
                """
                Adds exposures to a "set" of exposures. If 9ML objects were
                hashable could use a 'set'.
                """
                for pe in exposures_to_add:
                    if pe not in exposures:
                        exposures.append(pe)

            synapses = []
            connection_property_sets = []
            # FIXME: There has to be a way of avoiding this name clash
            if any(p.name == cls.CELL_COMP_NAME for p in receiving):
                raise Pype9RuntimeError(
                    "Cannot handle projections named '{}' (why would you "
                    "choose such a silly name?;)".format(cls.CELL_COMP_NAME))
            for proj in receiving:
                # Flatten response and plasticity into single dynamics class.
                # TODO: this should be no longer necessary when we move to
                # version 2 as response and plasticity elements will be
                # replaced by a synapse element in the standard. It will need
                # be copied at this point though as it is modified
                synapse, proj_conns = cls._flatten_synapse(proj)
                # Get all connections to/from the pre-synaptic cell
                pre_conns = [pc for pc in proj_conns
                             if 'pre' in (pc.receiver_role, pc.sender_role)]
                # Get all connections between the synapse and the post-synaptic
                # cell
                post_conns = [pc for pc in proj_conns if pc not in pre_conns]
                # Mapping of port connection role to sub-component name
                role2name = {'post': cls.CELL_COMP_NAME}
                # If the synapse is non-linear it can be combined into the
                # dynamics of the post-synaptic cell.
                try:
                    if not synapse.component_class.is_linear():
                        raise Pype9UnflattenableSynapseException()
                    role2name['synapse'] = proj.name
                    # Extract "connection weights" (any non-singular property
                    # value) from the synapse properties
                    connection_property_sets.extend(
                        cls._extract_connection_property_sets(synapse,
                                                              proj.name))
                    # Add the flattened synapse to the multi-dynamics sub
                    # components
                    sub_components[proj.name] = synapse.clone()
                    # Convert port connections between synpase and post-
                    # synaptic cell into internal port connections of a multi-
                    # dynamics object
                    internal_conns.extend(pc.assign_names_from_roles(role2name)
                                          for pc in post_conns)
                    # Expose ports that are needed for the pre-synaptic
                    # connections
                except Pype9UnflattenableSynapseException:
                    # All synapses (of this type) connected to a single post-
                    # synaptic cell cannot be flattened into a single component
                    # of a multi- dynamics object so an individual synapses
                    # must be created for each connection.
                    synapse_conns = [
                        pc.append_namespace_from_roles(
                            {'post': cls.CELL_COMP_NAME,
                             'pre': cls.CELL_COMP_NAME,
                             'synapse': proj.name}) for pc in post_conns]
                    synapses.append(SynapseProperties(proj.name, synapse,
                                                      synapse_conns))
                    # Add exposures to the post-synaptic cell for connections
                    # from the synapse
                    add_exposures(chain(*(
                        pc.expose_ports({'post': cls.CELL_COMP_NAME})
                        for pc in post_conns)))
                # Add exposures for connections to/from the pre synaptic cell
                add_exposures(
                    chain(*(pc.expose_ports(role2name)
                            for pc in pre_conns)))
                role2name['pre'] = cls.CELL_COMP_NAME
            # Add exposures for connections to/from the pre-synaptic cell in
            # populations.
            for proj in sending:
                # Not required after transition to version 2 syntax
                synapse, proj_conns = cls._flatten_synapse(proj)
                # Add send and receive exposures to list
                add_exposures(chain(*(
                    pc.expose_ports({'pre': cls.CELL_COMP_NAME})
                    for pc in proj_conns)))
            # Add all cell ports as multi-component exposures that aren't
            # connected internally in case the user would like to save them or
            # play data into them
            internal_cell_ports = set(chain(
                (pc.send_port_name for pc in internal_conns
                 if pc.sender_name == cls.CELL_COMP_NAME),
                (pc.receive_port_name for pc in internal_conns
                 if pc.receiver_name == cls.CELL_COMP_NAME)))
            add_exposures(
                BasePortExposure.from_port(p, cls.CELL_COMP_NAME)
                for p in pop.cell.ports if p.name not in internal_cell_ports)
            dynamics_properties = MultiDynamicsProperties(
                name=pop.name + '_cell', sub_components=sub_components,
                port_connections=internal_conns,
                port_exposures=exposures)
            component = MultiDynamicsWithSynapsesProperties(
                dynamics_properties.name,
                dynamics_properties, synapse_propertiess=synapses,
                connection_property_sets=connection_property_sets)
            array_name = pop.name
            component_arrays[array_name] = ComponentArray9ML(
                array_name, pop.size, component)
        selections = {}
        for sel in network_model.selections:
            selections[sel.name] = Selection9ML(
                sel.name, Concatenate9ML(component_arrays[p.name]
                                           for p in sel.populations))
        arrays_and_selections = dict(
            chain(iter(component_arrays.items()), iter(selections.items())))
        # Create ConnectionGroups from each port connection in Projection
        for proj in network_model.projections:
            _, proj_conns = cls._flatten_synapse(proj)
            # Get all connections to/from the pre-synaptic cell
            pre_conns = [pc for pc in proj_conns
                         if 'pre' in (pc.receiver_role, pc.sender_role)]
            # Create a connection group for each port connection of the
            # projection to/from the pre-synaptic cell
            for port_conn in pre_conns:
                ConnectionGroupClass = (
                    EventConnectionGroup9ML
                    if port_conn.communicates == 'event'
                    else AnalogConnectionGroup9ML)
                if len(pre_conns) > 1:
                    name = ('__'.join((proj.name,
                                       port_conn.sender_role,
                                       port_conn.send_port_name,
                                       port_conn.receiver_role,
                                       port_conn.receive_port_name)))
                else:
                    name = proj.name
                if port_conn.sender_role == 'pre':
                    connectivity = proj.connectivity
                    # If a connection from the pre-synaptic cell the delay
                    # is included
                    # TODO: In version 2 all port-connections will have
                    # their own delays
                    delay = proj.delay
                else:
                    # If a "reverse connection" to the pre-synaptic cell
                    # the connectivity needs to be inverted
                    connectivity = InversePyNNConnectivity(
                        proj.connectivity)
                    delay = 0.0 * un.s
                # Append sub-component namespaces to the source/receive
                # ports
                ns_port_conn = port_conn.append_namespace_from_roles(
                    {'post': cls.CELL_COMP_NAME,
                     'pre': cls.CELL_COMP_NAME,
                     'synapse': proj.name})
                conn_group = ConnectionGroupClass(
                    name,
                    arrays_and_selections[proj.pre.name],
                    arrays_and_selections[proj.post.name],
                    source_port=ns_port_conn.send_port_name,
                    destination_port=(ns_port_conn.receive_port_name),
                    connectivity=connectivity,
                    delay=delay)
                connection_groups[conn_group.name] = conn_group
        return component_arrays, connection_groups, selections
コード例 #14
0
"""

  This package mirrors the one in pyNN

  Author: Thomas G. Close ([email protected])
  Copyright: 2012-2014 Thomas G. Close.
  License: This file is part of the "NineLine" package, which is released under
           the MIT Licence, see LICENSE for details.
"""
from __future__ import absolute_import
import sys
from pype9.exceptions import Pype9RuntimeError
# Remove any system arguments that may conflict with
if '--debug' in sys.argv:
    raise Pype9RuntimeError(
        "'--debug' argument passed to script conflicts with an argument to "
        "nest, causing the import to stop at the NEST prompt")
import pyNN.nest  # @IgnorePep8
from pyNN.common.control import build_state_queries  # @IgnorePep8
from pyNN.nest.standardmodels.synapses import StaticSynapse  # @IgnorePep8
from pype9.simulate.common.network.base import (  # @IgnorePep8
    Network as BaseNetwork, ComponentArray as BaseComponentArray,
    ConnectionGroup as BaseConnectionGroup, Selection as BaseSelection)
import pyNN.nest.simulator as simulator  # @IgnorePep8
from .cell_wrapper import PyNNCellWrapperMetaClass  # @IgnorePep8
from .connectivity import PyNNConnectivity  # @IgnorePep8
from ..code_gen import CodeGenerator as CodeGenerator  # @IgnorePep8
from ..units import UnitHandler  # @IgnorePep8
from ..simulation import Simulation  # @IgnorePep8

(get_current_time, get_time_step, get_min_delay, get_max_delay, num_processes,
コード例 #15
0
ファイル: base.py プロジェクト: nsk6999/pype9
    def play(self, port_name, signal, properties=[]):
        """
        Plays an analog signal or train of events into a port of the dynamics
        array.

        Parameters
        ----------
        port_name : str
            The name of the port to play the signal into
        signal : neo.AnalogSignal | neo.SpikeTrain
            The signal to play into the cell
        properties : dict(str, nineml.Quantity)
            Connection properties when playing into a event receive port
            with static connection properties
        """
        port = self.celltype.model.component_class.receive_port(port_name)
        if port.nineml_type in ('EventReceivePort',
                                'EventReceivePortExposure'):
            # Shift the signal times to account for the minimum delay and
            # match the NEURON implementation
            try:
                spike_trains = Sequence(signal.rescale(pq.ms) -
                                        self._min_delay * pq.ms)
                source_size = 1
            except ValueError:  # Assume multiple signals
                spike_trains = []
                for spike_train in signal:
                    spike_train = (spike_train.rescale(pq.ms) -
                                   self._min_delay * pq.ms)
                    if any(spike_train <= 0.0):
                        raise Pype9RuntimeError(
                            "Some spike times are less than device delay ({}) "
                            "and so can't be played into cell ({})".format(
                                self._min_delay,
                                ', '.join(str(st) for st in spike_train[
                                    spike_train < self._min_delay])))
                    spike_trains.append(Sequence(spike_train))
                source_size = len(spike_trains)
            input_pop = self.PyNNPopulationClass(
                source_size, self.SpikeSourceArray,
                cellparams={'spike_times': spike_trains},
                label='{}-{}-input'.format(self.name, port_name))
#             self.celltype.model()._check_connection_properties(port_name,
#                                                                properties)
            if len(properties) > 1:
                raise NotImplementedError(
                    "Cannot handle more than one connection property per port")
            elif properties:
                weight = self.UnitHandler.scale_value(properties[0].quantity)
            else:
                weight = 1.0  # The weight var is not used
            connector = (self.OneToOneConnector()
                         if source_size > 1 else self.AllToAllConnector())
            input_proj = self.PyNNProjectionClass(
                input_pop, self, connector,
                self.SynapseClass(weight=weight, delay=self._min_delay),
                receptor_type=port_name,
                label='{}-{}-input_projection'.format(self.name, port_name))
            self._inputs[port_name] = (input_pop, input_proj)
        elif port.nineml_type in ('AnalogReceivePort', 'AnalogReducePort',
                                  'AnalogReceivePortExposure',
                                  'AnalogReducePortExposure'):
            raise NotImplementedError
#             # Signals are played into NEST cells include a delay (set to be the
#             # minimum), which is is subtracted from the start of the signal so
#             # that the effect of the signal aligns with other simulators
#             self._inputs[port_name] = nest.Create(
#                 'step_current_generator', 1,
#                 {'amplitude_values': pq.Quantity(signal, 'pA'),
#                  'amplitude_times': (
#                     signal.times.rescale(pq.ms) -
#                     controller.device_delay * pq.ms),
#                  'start': float(signal.t_start.rescale(pq.ms)),
#                  'stop': float(signal.t_stop.rescale(pq.ms))})
#             nest.Connect(self._inputs[port_name], self._cell,
#                          syn_spec={
#                              "receptor_type": self._receive_ports[port_name],
#                              'delay': controller.device_delay})
        else:
            raise Pype9RuntimeError(
                "Unrecognised port type '{}' to play signal into".format(port))
コード例 #16
0
ファイル: testing.py プロジェクト: nsk6999/pype9
 def _create_NEST(self, nest_name):
     trans_params = {}
     for prop in self.properties.properties:
         name = prop.name
         value = prop.value
         try:
             varname, scale = self.nest_translations[name]
             value = value * scale
         except (ValueError, KeyError):
             varname = self.nest_translations.get(name, name)
         value = UnitHandlerNEST.scale_value(Quantity(value, prop.units))
         if varname is not None:
             trans_params[varname] = value
     self.nest_cell = nest.Create(nest_name, 1, trans_params)
     try:
         receptor_types = nest.GetDefaults(nest_name)['receptor_types']
     except KeyError:
         receptor_types = None
     if self.input_signal is not None:
         port_name, signal = self.input_signal
         generator = nest.Create(
             'step_current_generator', 1, {
                 'amplitude_values':
                 numpy.ravel(pq.Quantity(signal, 'pA')),
                 'amplitude_times':
                 numpy.ravel(numpy.asarray(signal.times.rescale(pq.ms))) -
                 self.device_delay,
                 'start':
                 float(signal.t_start.rescale(pq.ms)),
                 'stop':
                 float(signal.t_stop.rescale(pq.ms))
             })
         nest.Connect(
             generator,
             self.nest_cell,
             syn_spec={
                 'receptor_type':
                 (receptor_types[port_name] if receptor_types else 0),
                 'delay':
                 self.device_delay
             })
     if self.input_train is not None:
         port_name, signal, connection_properties = self.input_train
         try:
             _, scale = self.nest_translations[port_name]
         except KeyError:
             scale = 1.0
         # FIXME: Should scale units
         weight = connection_properties[0].value * scale
         spike_times = (numpy.asarray(signal.rescale(pq.ms)) -
                        self.device_delay)
         if any(spike_times < 0.0):
             raise Pype9RuntimeError(
                 "Some spike are less than minimum delay and so can't be "
                 "played into cell ({})".format(', '.join(
                     str(t) for t in spike_times[
                         spike_times < self.device_delay])))
         generator = nest.Create('spike_generator', 1,
                                 {'spike_times': spike_times})
         nest.Connect(
             generator,
             self.nest_cell,
             syn_spec={
                 'receptor_type':
                 (receptor_types[port_name] if receptor_types else 0),
                 'delay':
                 self.device_delay,
                 'weight':
                 float(weight)
             })
     self.nest_multimeter = nest.Create(
         'multimeter', 1, {"interval": self.to_float(self.dt, 'ms')})
     nest.SetStatus(self.nest_multimeter,
                    {'record_from': [self.nest_state_variable]})
     nest.Connect(self.nest_multimeter,
                  self.nest_cell,
                  syn_spec={'delay': self.device_delay})
     trans_states = {}
     for name, qty in self.initial_states.items():
         try:
             varname, scale = self.nest_translations[name]
             qty = qty * scale
         except (ValueError, KeyError):
             varname = self.nest_translations.get(name, name)
         value = UnitHandlerNEST.scale_value(qty)
         if varname is not None:
             trans_states[varname] = value
     nest.SetStatus(self.nest_cell, trans_states)
コード例 #17
0
ファイル: testing.py プロジェクト: nsk6999/pype9
 def __init__(self,
              nineml_model=None,
              properties=None,
              initial_states=None,
              initial_regime=None,
              state_variable='v',
              dt=0.01,
              simulators=None,
              neuron_ref=None,
              nest_ref=None,
              input_signal=None,
              input_train=None,
              neuron_translations=None,
              nest_translations=None,
              neuron_build_args=None,
              nest_build_args=None,
              min_delay=0.1,
              device_delay=0.1,
              max_delay=10.0,
              extra_mechanisms=None,
              extra_point_process=None,
              auxiliary_states=None):
     if nineml_model is not None and not simulators:
         raise Pype9RuntimeError(
             "No simulators specified to simulate the 9ML model '{}'."
             "Add either 'neuron', 'nest' or both to the positional "
             "arguments".format(nineml_model.name))
     self.simulate_neuron = 'neuron' in simulators
     self.simulate_nest = 'nest' in simulators
     self.dt = self.to_float(dt, 'ms')
     self.state_variable = state_variable
     self.nineml_model = nineml_model
     self.properties = properties if properties is not None else {}
     self.neuron_ref = neuron_ref if self.simulate_neuron else None
     self.nest_ref = nest_ref if self.simulate_nest else None
     self.simulators = simulators if simulators is not None else []
     self.extra_mechanisms = (extra_mechanisms
                              if extra_mechanisms is not None else [])
     self.extra_point_process = extra_point_process
     self.neuron_translations = (neuron_translations
                                 if neuron_translations is not None else {})
     self.nest_translations = (nest_translations
                               if nest_translations is not None else {})
     self.initial_states = (initial_states
                            if initial_states is not None else {})
     self.initial_regime = initial_regime
     self.auxiliary_states = (auxiliary_states
                              if auxiliary_states is not None else [])
     self.input_signal = input_signal
     self.input_train = input_train
     self.build_args = {
         'nest': (nest_build_args if nest_build_args is not None else {}),
         'neuron':
         (neuron_build_args if neuron_build_args is not None else {})
     }
     self.nml_cells = {}
     if self.state_variable in self.nest_translations:
         self.nest_state_variable = self.nest_translations[
             self.state_variable][0]
     else:
         self.nest_state_variable = self.state_variable
     if self.state_variable in self.neuron_translations:
         self.neuron_state_variable = self.neuron_translations[
             self.state_variable][0]
     else:
         self.neuron_state_variable = self.state_variable
     self.min_delay = min_delay
     self.device_delay = device_delay
     self.max_delay = max_delay
コード例 #18
0
ファイル: base.py プロジェクト: nsk6999/pype9
    def transform_for_build(self, name, component_class, **kwargs):
        """
        Copies and transforms the component class to match the format of the
        simulator (overridden in derived class)

        Parameters
        ----------
        name : str
            The name of the transformed component class
        component_class : nineml.Dynamics
            The component class to be transformed
        """
        self._set_build_props(component_class, **kwargs)
        if not isinstance(component_class, WithSynapses):
            raise Pype9RuntimeError(
                "'component_class' must be a DynamicsWithSynapses object")
        # ---------------------------------------------------------------------
        # Clone original component class
        # ---------------------------------------------------------------------
        trfrm = component_class.dynamics.flatten()
        # ---------------------------------------------------------------------
        # Get the membrane voltage and convert it to 'v'
        # ---------------------------------------------------------------------
        try:
            name = kwargs['membrane_voltage']
            try:
                orig_v = component_class.element(
                    name, nineml_children=Dynamics.nineml_children)
            except KeyError:
                raise Pype9BuildError(
                    "Could not find specified membrane voltage '{}'"
                    .format(name))
        except KeyError:  # Guess voltage from its dimension if not supplied
            candidate_vs = [cv for cv in component_class.state_variables
                            if cv.dimension == un.voltage]
            if len(candidate_vs) == 0:
                candidate_vs = [
                    cv for cv in component_class.analog_receive_ports
                    if cv.dimension == un.voltage]
            if len(candidate_vs) == 1:
                orig_v = candidate_vs[0]
                logger.info("Guessing that '{}' is the membrane voltage"
                            .format(orig_v))
            elif len(candidate_vs) > 1:
                try:
                    orig_v = next(c for c in candidate_vs if c.name == 'v')
                    logger.info("Guessing that '{}' is the membrane voltage"
                                .format(orig_v))
                except StopIteration:
                    raise Pype9BuildError(
                        "Could not guess the membrane voltage, candidates: "
                        "'{}'" .format("', '".join(v.name
                                                   for v in candidate_vs)))
            else:
                orig_v = None
                logger.info(
                    "Can't find candidate for the membrane voltage in "
                    "state_variables '{}' or analog_receive_ports '{}', "
                    "treating '{}' as an \"artificial cell\"".format(
                        "', '".join(
                            sv.name for sv in component_class.state_variables),
                        "', '".join(
                            p.name
                            for p in component_class.analog_receive_ports),
                        component_class.name))
        if orig_v is not None:
            # Map voltage to hard-coded 'v' symbol
            if orig_v.name != 'v':
                trfrm.rename_symbol(orig_v.name, 'v')
                v = trfrm.state_variable('v')
                v.annotations.set((BUILD_TRANS, PYPE9_NS),
                                  TRANSFORM_SRC, orig_v)
            else:
                v = trfrm.state_variable('v')
            # Add annotations to the original and build models
            component_class.annotations.set((BUILD_TRANS, PYPE9_NS),
                                            MEMBRANE_VOLTAGE, orig_v.name)  # @IgnorePep8
            trfrm.annotations.set((BUILD_TRANS, PYPE9_NS),
                                  MEMBRANE_VOLTAGE, 'v')
            # Remove associated analog send port if present
            try:
                trfrm.remove(trfrm.analog_send_port('v'))
            except KeyError:
                pass
            # Need to convert to AnalogReceivePort if v is a StateVariable
            if isinstance(v, StateVariable):
                self._transform_full_component(trfrm, component_class, v,
                                               **kwargs)
                trfrm.annotations.set((BUILD_TRANS, PYPE9_NS),
                                      MECH_TYPE, FULL_CELL_MECH)
            else:
                raise NotImplementedError(
                    "Build sub-components is not supported in PyPe9 v0.1")
        else:
            trfrm.annotations.set((BUILD_TRANS, PYPE9_NS), MECH_TYPE,
                                  ARTIFICIAL_CELL_MECH)

        # -----------------------------------------------------------------
        # Insert dummy aliases for parameters (such as capacitance) that
        # now do not show up in the inferred interface for the transformed
        # class (i.e. that were only # present in the voltage time derivative)
        # -----------------------------------------------------------------

        # Infer required parameters
        inferred = DynamicsInterfaceInferer(trfrm)

        for parameter in list(trfrm.parameters):
            if parameter.name not in inferred.parameter_names:
                trfrm.add(Alias(parameter.name + '___dummy', parameter.name))

        # -----------------------------------------------------------------
        # Validate the transformed component class and construct prototype
        # -----------------------------------------------------------------

        trfrm.validate()
        trfrm_with_syn = DynamicsWithSynapses(
            name, trfrm, component_class.synapses,
            component_class.connection_parameter_sets)
        # Retun a prototype of the transformed class
        return trfrm_with_syn