# Copyright (c) 2015 The University of Manchester
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations
from typing import List, Sequence, TYPE_CHECKING, Union, Optional
from spinn_utilities.config_holder import get_config_bool
from pacman.model.graphs.application import ApplicationVertex
from spynnaker.pyNN.models.neural_projections.connectors import (
AbstractConnector, AbstractGenerateConnectorOnMachine)
from spynnaker.pyNN.models.neuron.synapse_dynamics import (
AbstractGenerateOnMachine)
from spynnaker.pyNN.types import (Delay_Types, Weight_Types)
from spynnaker.pyNN.utilities.constants import SPIKE_PARTITION_ID
if TYPE_CHECKING:
from spynnaker.pyNN.models.populations import Population, PopulationView
from spynnaker.pyNN.models.neuron import ConnectionHolder
from spynnaker.pyNN.models.neuron.synapse_dynamics import (
AbstractSynapseDynamics)
class SynapseInformation(object):
"""
Contains the synapse information including the connector, synapse type
and synapse dynamics.
"""
# Made by a Projection
__slots__ = (
"__connector",
"__pre_population",
"__post_population",
"__prepop_is_view",
"__postpop_is_view",
"__synapse_dynamics",
"__synapse_type",
"__receptor_type",
"__weights",
"__delays",
"__pre_run_connection_holders",
"__synapse_type_from_dynamics",
"__download_on_pause",
"__partition_id")
def __init__(self, connector: AbstractConnector,
pre_population: Union[Population, PopulationView],
post_population: Union[Population, PopulationView],
prepop_is_view: bool, postpop_is_view: bool,
synapse_dynamics: AbstractSynapseDynamics,
synapse_type: int, receptor_type: str,
synapse_type_from_dynamics: bool,
weights: Weight_Types = None,
delays: Delay_Types = None,
download_on_pause: bool = False,
partition_id: Optional[str] = None):
"""
:param AbstractConnector connector:
The connector connected to the synapse
:param pre_population: The population sending spikes to the synapse
:type pre_population: ~spynnaker.pyNN.models.populations.Population or
~spynnaker.pyNN.models.populations.PopulationView
:param post_population: The population hosting the synapse
:type post_population: ~spynnaker.pyNN.models.populations.Population
or ~spynnaker.pyNN.models.populations.PopulationView
:param bool prepop_is_view: Whether the ``pre_population`` is a view
:param bool postpop_is_view: Whether the ``post_population`` is a view
:param AbstractSynapseDynamics synapse_dynamics:
The dynamic behaviour of the synapse
:param int synapse_type: The type of the synapse
:param str receptor_type: Description of the receptor (e.g. excitatory)
:param bool synapse_type_from_dynamics:
Whether the synapse type came from synapse dynamics
:param weights: The synaptic weights
:type weights: float or list(float) or ~numpy.ndarray(float) or None
:param delays: The total synaptic delays
:type delays: float or list(float) or ~numpy.ndarray(float) or None
:param bool download_on_pause:
Whether to download the synapse matrix when the simulation pauses
:param partition_id:
The partition id for the application edge when not standard; if
None, the standard SPIKE_PARTITION_ID is used
:type partition_id: str or None
"""
self.__connector = connector
self.__pre_population = pre_population
self.__post_population = post_population
self.__prepop_is_view = prepop_is_view
self.__postpop_is_view = postpop_is_view
self.__synapse_dynamics = synapse_dynamics
self.__synapse_type = synapse_type
self.__receptor_type = receptor_type
assert (delays is not None)
self.__weights = weights
self.__delays = delays
self.__synapse_type_from_dynamics = synapse_type_from_dynamics
self.__download_on_pause = download_on_pause
self.__partition_id = partition_id or SPIKE_PARTITION_ID
# Make a list of holders to be updated
self.__pre_run_connection_holders: List[ConnectionHolder] = list()
@property
def connector(self) -> AbstractConnector:
"""
The connector connected to the synapse.
:rtype: AbstractConnector
"""
return self.__connector
@property
def pre_population(self) -> Union[Population, PopulationView]:
"""
The population sending spikes to the synapse.
:rtype: ~spynnaker.pyNN.models.populations.Population or
~spynnaker.pyNN.models.populations.PopulationView
"""
return self.__pre_population
@property
def post_population(self) -> Union[Population, PopulationView]:
"""
The population hosting the synapse.
:rtype: ~spynnaker.pyNN.models.populations.Population or
~spynnaker.pyNN.models.populations.PopulationView
"""
return self.__post_population
@property
def pre_vertex(self) -> ApplicationVertex:
"""
The vertex sending spikes to the synapse.
:rtype: ApplicationVertex
"""
# pylint: disable=protected-access
return self.__pre_population._vertex
@property
def post_vertex(self) -> ApplicationVertex:
"""
The vertex hosting the synapse.
:rtype: ApplicationVertex
"""
# pylint: disable=protected-access
return self.__post_population._vertex
@property
def n_pre_neurons(self) -> int:
"""
The number of neurons in the pre-population.
:rtype: int
"""
return self.__pre_population.size
@property
def n_post_neurons(self) -> int:
"""
The number of neurons in the post-population.
:rtype: int
"""
return self.__post_population.size
@property
def prepop_is_view(self) -> bool:
"""
Whether the :py:meth:`pre_population` is a view.
:rtype: bool
"""
return self.__prepop_is_view
@property
def postpop_is_view(self) -> bool:
"""
Whether the :py:meth:`post_population` is a view.
:rtype: bool
"""
return self.__postpop_is_view
@property
def synapse_dynamics(self):
"""
The dynamic behaviour of the synapse.
:rtype: AbstractSynapseDynamics
"""
return self.__synapse_dynamics
@property
def synapse_type(self) -> int:
"""
The type of the synapse. An index into the set of synapse types
supported by a neuron.
:rtype: int
"""
return self.__synapse_type
@property
def receptor_type(self) -> str:
"""
A string representing the receptor type.
:rtype: str
"""
return self.__receptor_type
@property
def weights(self) -> Weight_Types:
"""
The synaptic weights (if any).
:rtype: float or ~numpy.ndarray(float64) or str or RandomDistribution
"""
return self.__weights
@property
def delays(self) -> Delay_Types:
"""
The total synaptic delays (if any).
:rtype: float or ~numpy.ndarray(float64) or str or RandomDistribution
"""
return self.__delays
@property
def pre_run_connection_holders(self) -> Sequence[ConnectionHolder]:
"""
The list of connection holders to be filled in before run.
:rtype: list(ConnectionHolder)
"""
return self.__pre_run_connection_holders
@property
def synapse_type_from_dynamics(self) -> bool:
"""
Whether the synapse type comes from the synapse dynamics.
:rtype: bool
"""
return self.__synapse_type_from_dynamics
@property
def download_on_pause(self) -> bool:
"""
Whether to download the synapse matrix when the simulation pauses.
:rtype: bool
"""
return self.__download_on_pause
@download_on_pause.setter
def download_on_pause(self, download_on_pause: bool):
"""
Set whether to download the synapse matrix when the simulation pauses.
:param bool download_on_pause:
Whether to download the synapse matrix when the simulation pauses
"""
self.__download_on_pause = download_on_pause
@property
def partition_id(self) -> str:
"""
The partition id for the application edge
:rtype: str
"""
return self.__partition_id