def get_keys(self, key_array=None, offset=0, n_keys=None):
        """ Get the ordered list of keys that the combination allows

        :param key_array: \
            Optional array into which the returned keys will be placed
        :type key_array: array-like of int
        :param offset: \
            Optional offset into the array at which to start placing keys
        :type offset: int
        :param n_keys: \
            Optional limit on the number of keys returned. If less than this\
            number of keys are available, only the keys available will be added
        :type n_keys: int
        :return: A tuple of an array of keys and the number of keys added to\
            the array
        :rtype: tuple(array-like of int, int)
        """
        if self._key_space.user != constants.USER_FIELDS.NENGO.value:
            return BaseKeyAndMask.get_keys(key_array, offset, n_keys)
        else:
            # Get the position of the zeros in the mask - assume 32-bits
            unwrapped_mask = numpy.unpackbits(
                numpy.asarray([self._mask], dtype=">u4").view(dtype="uint8"))
            zeros = numpy.where(unwrapped_mask == 0)[0]

            # If there are no zeros, there is only one key in the range, so
            # return that
            if len(zeros) == 0:
                if key_array is None:
                    key_array = numpy.zeros(1, dtype=">u4")
                key_array[offset] = self._base_key
                return key_array, 1

            # We now know how many values there are - 2^len(zeros)
            max_n_keys = 2**len(zeros)
            if key_array is not None and len(key_array) < max_n_keys:
                max_n_keys = len(key_array)
            if n_keys is None or n_keys > max_n_keys:
                n_keys = max_n_keys
            if key_array is None:
                key_array = numpy.zeros(n_keys, dtype=">u4")

            # get keys
            keys = list()
            for index in range(0, n_keys):
                args = {constants.INDEX_FIELD_ID: index}
                keys.append(self._key_space(**args).get_value())

            # for each key, create its key with the idea of a neuron ID being
            # continuous and live at an offset position from the bottom of
            # the key
            for index, key in enumerate(keys):
                key_array[index + offset] = key
            return key_array, n_keys
 def test_base_key_and_mask(self):
     with self.assertRaises(PacmanConfigurationException):
         BaseKeyAndMask(0xF0, 0x40)
     bkm1 = BaseKeyAndMask(0x40, 0xF0)
     assert bkm1 == bkm1
     assert bkm1 != []
     assert str(bkm1) == "KeyAndMask:0x40:0xf0"
     assert bkm1.n_keys == 268435456
     bkm2 = BaseKeyAndMask(0x40000000, _32_BITS & ~1)
     assert bkm1 != bkm2
     assert bkm2.n_keys == 2
     k, n = bkm2.get_keys()
     assert k.tolist() == [1073741824, 1073741825]
     assert n == 2
 def test_base_key_and_mask(self):
     with self.assertRaises(PacmanConfigurationException):
         BaseKeyAndMask(0xF0, 0x40)
     bkm1 = BaseKeyAndMask(0x40, 0xF0)
     assert bkm1 == bkm1
     assert bkm1 != []
     assert str(bkm1) == "KeyAndMask:0x40:0xf0"
     assert bkm1.n_keys == 268435456
     bkm2 = BaseKeyAndMask(0x40000000, FULL_MASK & ~1)
     assert bkm1 != bkm2
     assert bkm2.n_keys == 2
     k, n = bkm2.get_keys()
     assert k.tolist() == [1073741824, 1073741825]
     assert n == 2