示例#1
0
文件: base.py 项目: tclose/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 = set()
         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
                 # 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.
                 synapses.append(SynapseProperties(proj.name, synapse,
                                                   post_conns))
                 # Add exposures to the post-synaptic cell for connections
                 # from the synapse
                 exposures.update(
                     chain(*(pc.expose_ports({'post': cls.CELL_COMP_NAME})
                             for pc in post_conns)))
             # Add exposures for connections to/from the pre synaptic cell
             exposures.update(
                 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
             exposures.update(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)))
         exposures.update(
             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, sub_components=sub_components,
             port_connections=internal_conns, port_exposures=exposures)
         component = MultiDynamicsWithSynapsesProperties(
             dynamics_properties.name,
             dynamics_properties, synapses_properties=synapses,
             connection_property_sets=connection_property_sets)
         component_arrays[pop.name] = ComponentArray9ML(pop.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.operation.items)))
     arrays_and_selections = dict(
         chain(component_arrays.iteritems(), selections.iteritems()))
     # 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
示例#2
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
示例#3
0
文件: base.py 项目: tclose/PyPe9
 def _flatten_synapse(cls, projection_model):
     """
     Flattens the reponse and plasticity dynamics into a single synapse
     element (will be 9MLv2 format) and updates the port connections
     to match the changed object.
     """
     role2name = {'response': 'psr', 'plasticity': 'pls'}
     syn_comps = {
         role2name['response']: projection_model.response,
         role2name['plasticity']: projection_model.plasticity}
     # Get all projection port connections that don't project to/from
     # the "pre" population and convert them into local MultiDynamics
     # port connections of the synapse
     syn_internal_conns = (
         pc.__class__(
             sender_name=role2name[pc.sender_role],
             receiver_name=role2name[pc.receiver_role],
             send_port=pc.send_port_name, receive_port=pc.receive_port_name)
         for pc in projection_model.port_connections
         if (pc.sender_role in ('plasticity', 'response') and
             pc.receiver_role in ('plasticity', 'response')))
     receive_conns = [pc for pc in projection_model.port_connections
                      if (pc.sender_role in ('pre', 'post') and
                          pc.receiver_role in ('plasticity', 'response'))]
     send_conns = [pc for pc in projection_model.port_connections
                   if (pc.sender_role in ('plasticity', 'response') and
                       pc.receiver_role in ('pre', 'post'))]
     syn_exps = chain(
         (BasePortExposure.from_port(pc.send_port,
                                     role2name[pc.sender_role])
          for pc in send_conns),
         (BasePortExposure.from_port(pc.receive_port,
                                     role2name[pc.receiver_role])
          for pc in receive_conns))
     synapse = MultiDynamicsProperties(
         name=(projection_model.name + '_syn'),
         sub_components=syn_comps,
         port_connections=syn_internal_conns,
         port_exposures=syn_exps)
     port_connections = list(chain(
         (pc.__class__(sender_role=pc.sender_role,
                       receiver_role='synapse',
                       send_port=pc.send_port_name,
                       receive_port=append_namespace(
                           pc.receive_port_name,
                           role2name[pc.receiver_role]))
          for pc in receive_conns),
         (pc.__class__(sender_role='synapse',
                       receiver_role=pc.receiver_role,
                       send_port=append_namespace(
                           pc.send_port_name,
                           role2name[pc.sender_role]),
                       receive_port=pc.receive_port_name)
          for pc in send_conns),
         (pc for pc in projection_model.port_connections
          if (pc.sender_role in ('pre', 'post') and
              pc.receiver_role in ('pre', 'post')))))
     # A bit of a hack in order to bind the port_connections
     dummy_container = namedtuple('DummyContainer', 'pre post synapse')(
         projection_model.pre, projection_model.post, synapse)
     for port_connection in port_connections:
         port_connection.bind(dummy_container, to_roles=True)
     return synapse, port_connections
示例#4
0
文件: base.py 项目: nsk6999/pype9
 def _flatten_synapse(cls, projection_model):
     """
     Flattens the reponse and plasticity dynamics into a single synapse
     element (will be 9MLv2 format) and updates the port connections
     to match the changed object.
     """
     role2name = {'response': 'psr', 'plasticity': 'pls'}
     syn_comps = {
         role2name['response']: projection_model.response,
         role2name['plasticity']: projection_model.plasticity}
     # Get all projection port connections that don't project to/from
     # the "pre" population and convert them into local MultiDynamics
     # port connections of the synapse
     syn_internal_conns = (
         pc.__class__(
             sender_name=role2name[pc.sender_role],
             receiver_name=role2name[pc.receiver_role],
             send_port_name=pc.send_port_name,
             receive_port_name=pc.receive_port_name)
         for pc in projection_model.port_connections
         if (pc.sender_role in ('plasticity', 'response') and
             pc.receiver_role in ('plasticity', 'response')))
     receive_conns = [pc for pc in projection_model.port_connections
                      if (pc.sender_role in ('pre', 'post') and
                          pc.receiver_role in ('plasticity', 'response'))]
     send_conns = [pc for pc in projection_model.port_connections
                   if (pc.sender_role in ('plasticity', 'response') and
                       pc.receiver_role in ('pre', 'post'))]
     syn_exps = chain(
         (BasePortExposure.from_port(pc.send_port,
                                     role2name[pc.sender_role])
          for pc in send_conns),
         (BasePortExposure.from_port(pc.receive_port,
                                     role2name[pc.receiver_role])
          for pc in receive_conns))
     synapse = MultiDynamicsProperties(
         name=(projection_model.name + '_syn'),
         sub_components=syn_comps,
         port_connections=syn_internal_conns,
         port_exposures=syn_exps)
     port_connections = list(chain(
         (pc.__class__(sender_role=pc.sender_role,
                       receiver_role='synapse',
                       send_port_name=pc.send_port_name,
                       receive_port_name=append_namespace(
                           pc.receive_port_name,
                           role2name[pc.receiver_role]))
          for pc in receive_conns),
         (pc.__class__(sender_role='synapse',
                       receiver_role=pc.receiver_role,
                       send_port_name=append_namespace(
                           pc.send_port_name,
                           role2name[pc.sender_role]),
                       receive_port_name=pc.receive_port_name)
          for pc in send_conns),
         (pc for pc in projection_model.port_connections
          if (pc.sender_role in ('pre', 'post') and
              pc.receiver_role in ('pre', 'post')))))
     # A bit of a hack in order to bind the port_connections
     dummy_container = namedtuple('DummyContainer', 'pre post synapse')(
         projection_model.pre, projection_model.post, synapse)
     for port_connection in port_connections:
         port_connection.bind(dummy_container, to_roles=True)
     return synapse, port_connections