Source code for spynnaker.pyNN.models.common.parameter_holder

# Copyright (c) 2017 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 pyNN.random import RandomDistribution
from spinn_utilities.helpful_functions import is_singleton


class ParameterHolder(object):
    """
    Holds a set of parameters and state variables to be returned in a
    PyNN-specific format.
    """

    __slots__ = (
        # A list of items of data that are to be present in each element
        "__data_items_to_return",

        # Function call to get the values
        "__get_call",

        # The merged parameters formed just before the data is read
        "__data_items",

        # A selector to use if requested
        "__selector"
    )

    def __init__(self, data_items_to_return, get_call, selector=None):
        """
        :param data_items_to_return: A list of data fields to be returned
        :type data_items_to_return: list(str) or tuple(str)
        :param get_call: A function to call to read a value
        :type get_call: callable(str, selector=None)->list
        :param selector: a description of the subrange to accept,
            or `None` for all. See:
            :py:meth:`~spinn_utilities.ranged.AbstractSized.selector_to_ids`
        :type selector: None or slice or int or list(bool) or list(int)
        """
        # pylint: disable=too-many-arguments
        self.__data_items_to_return = data_items_to_return
        self.__get_call = get_call
        self.__data_items = None
        self.__selector = selector

    def _safe_read_values(self, parameter):
        values = self.__get_call(parameter, self.__selector)

        # The values must be a single item, a list or a random distribution;
        # if a random distribution we must not have generated yet!
        if isinstance(values, RandomDistribution):
            raise ValueError(
                "Although it is possible to request the values"
                " before the simulation has run, it is not possible to read"
                " those values until after the simulation has run.  Please run"
                f" the simulation before reading {parameter}.")

        if self.__selector is not None and is_singleton(self.__selector):
            return values[0]
        return values

    def _get_data_items(self):
        """
        Merges the parameters and values in to the final data items
        """
        # If there are already merged connections cached, return those
        if self.__data_items is not None:
            return self.__data_items

        # If there is just one item to return, return the values stored
        if is_singleton(self.__data_items_to_return):
            self.__data_items = self._safe_read_values(
                self.__data_items_to_return)
            return self.__data_items

        # If there are multiple items to return, form a list
        self.__data_items = {
            param: self._safe_read_values(param)
            for param in self.__data_items_to_return}

        return self.__data_items

    def __getitem__(self, s):
        data = self._get_data_items()
        return data[s]

    def __len__(self):
        data = self._get_data_items()
        return len(data)

    def __iter__(self):
        data = self._get_data_items()
        return iter(data)

    def __str__(self):
        data = self._get_data_items()
        return data.__str__()

    def __repr__(self):
        data = self._get_data_items()
        return data.__repr__()

    def __contains__(self, item):
        data = self._get_data_items()
        return item in data

    def __getattr__(self, name):
        data = self._get_data_items()
        return getattr(data, name)

    def __eq__(self, other):
        data = self._get_data_items()
        return data == other

    def __hash__(self):
        data = self._get_data_items()
        return hash(data)

[docs] def keys(self): data = self._get_data_items() return data.keys()
[docs] def values(self): data = self._get_data_items() return data.items()
[docs] def items(self): data = self._get_data_items() return data.items()