Source code for bb_utils.ids

import numpy as np

from bb_utils.visualization import TagArtist


[docs]class BeesbookID: def __init__(self, bee_id): if type(bee_id) is not np.array: bee_id = np.array(bee_id) bee_id = np.round(bee_id).astype(np.int) self.binary_12 = bee_id @staticmethod def _dec_to_bin(bee_id): assert(bee_id < 4096) bee_id = (np.array([2 ** i for i in range(11, -1, -1)]) & bee_id) return bee_id.astype(np.bool).astype(np.int)
[docs] @classmethod def from_bin_9(cls, bee_id): """Initialize ID using bin_9 representation. Note: Bits are in most significant bit first order starting at the 9 o'clock position on the tag in clockwise orientation. Arguments: bee_id: ID in bin_9 representation """ return cls(np.roll(bee_id, -3, axis=0))
[docs] @classmethod def from_bin_12(cls, bee_id): """Initialize ID using bin_12 representation. Note: Bits are in most significant bit first order starting at the 12 o'clock position on the tag in clockwise orientation. This is the same as the bb_binary representation. See https://arxiv.org/pdf/1611.01331.pdf Figure 1(a) for a graphical representation. Arguments: bee_id: ID in bin_12 representation """ return cls(bee_id)
[docs] @classmethod def from_dec_9(cls, bee_id): """Initialize ID using decimal representation called 'dec_9' by Maria Sparenberg. Note: In this representation, lower decimal IDs roughly correspond to earlier hatch dates. This is the same as the 'ferwar' representation. Arguments: bee_id: ID in dec_9 representation """ return cls.from_ferwar(bee_id)
[docs] @classmethod def from_dec_12(cls, bee_id): """Initialize ID using decimal representation called 'dec_12' by Maria Sparenberg. Arguments: bee_id: ID in dec_12 representation """ return cls(cls._dec_to_bin(bee_id))
[docs] @classmethod def from_dec_12_reverse(cls, bee_id): """Initialize ID using decimal representation used in the tracking ground truth by Jakob Mischek. Arguments: bee_id: ID in dec_12_reverse representation """ return cls(cls._dec_to_bin(bee_id)[::-1])
[docs] @classmethod def from_ferwar(cls, bee_id): """Initialize ID using decimal representation originally used by Fernando Wario. Note: In this representation, lower decimal IDs roughly correspond to earlier hatch dates. This is the same as the 'dec_9' representation. Arguments: bee_id: ID in ferwar representation """ needs_inverse_parity = bee_id >= 2048 bee_id = bee_id - 2048 if needs_inverse_parity else bee_id bin_9 = cls._dec_to_bin(bee_id) bin_9 = np.roll(bin_9, -1, axis=0) parity = np.sum(bin_9[:-1]) % 2 if needs_inverse_parity: bin_9[-1] = 1 - parity else: bin_9[-1] = parity return cls.from_bin_9(bin_9)
[docs] @classmethod def from_bb_binary(cls, bee_id): """Initialize ID using bb_binary representation. Note: Bits are in most significant bit first order starting at the 12 o'clock position on the tag in clockwise orientation. See https://arxiv.org/pdf/1611.01331.pdf Figure 1(a) for a graphical representation. Arguments: bee_id: ID in bb_binary representation """ return cls(bee_id)
[docs] def as_dec_9(self): """Return ID decimal representation called 'dec_9' by Maria Sparenberg. Note: In this representation, lower decimal IDs roughly correspond to earlier hatch dates. This is the same as the ferwar representation. Returns: :obj:`int`: ID in 'dec_9' decimal representation """ return self.as_ferwar()
[docs] def as_dec_12(self): """Return ID decimal representation called 'dec_12' by Maria Sparenberg. Returns: :obj:`int`: ID in 'dec_12' decimal representation """ return np.sum(2 ** np.array(range(12))[::-1] * self.binary_12)
[docs] def as_bin_9(self): """Return ID in 'bin_9' binary representation. Note: Bits are in most significant bit first order starting at the 9 o'clock position on the tag in clockwise orientation. Returns: :obj:`np.array`: ID in bb_binary representation """ return np.roll(self.binary_12, 3, axis=0)
[docs] def as_ferwar(self): """Return ID decimal representation originally used by Fernando Wario. Note: In this representation, lower decimal IDs roughly correspond to earlier hatch dates. This is the same as the 'dec_9' representation. Returns: :obj:`int`: ID in ferwar decimal representation """ # convert to decimal id using 11 least significant bits bin_9 = self.as_bin_9() decimal_id = int(''.join([str(c) for c in bin_9[:11]]), 2) parity_bit = bin_9[-1] # determine what kind of parity bit was used and add 2^11 to decimal id # if uneven parity bit was used if (np.sum(bin_9[:11]) % 2) != parity_bit: decimal_id += 2048 return decimal_id
[docs] def as_bb_binary(self): """Return ID in decoder binary representation. Note: Bits are in most significant bit first order starting at the 12 o'clock position on the tag in clockwise orientation. See https://arxiv.org/pdf/1611.01331.pdf Figure 1(a) for a graphical representation. Returns: :obj:`np.array`: ID in bb_binary representation """ return self.binary_12
[docs] @staticmethod def batch_bb_binary_to_ferwar(ids): """Vectorized conversion of bb_binary IDs to ferwar decimal IDs. Note: This function can be used when a large batch of IDs has to be converted. It should be significantly faster than constructing a BeesbookID object and calling as_ferwar() for each ID. Arguments: :obj:`np.array`: array of bb_binary IDs with shape [batch_size, 12] Returns: :obj:`np.array`: array of decimal IDs in ferwar representation """ binary_ids = np.round(ids).astype(np.int) adjusted_ids = np.roll(binary_ids, 3, axis=1) # convert to decimal id using 11 least significant bits decimal_ids = [int(''.join([str(c) for c in id[:11]]), 2) for id in adjusted_ids] # determine what kind of parity bit was used and add 2^11 to decimal id # uneven parity bit was used decimal_ids = np.array(decimal_ids) decimal_ids[(np.sum(adjusted_ids, axis=1) % 2) == 1] += 2048 return decimal_ids
def __repr__(self): return 'BeesbookID(bb_binary|bin_12: {}, ferwar|dec_9 decimal: {})'.format( ''.join(self.binary_12.astype(str)), self.as_ferwar()) def _repr_png_(self): print(self.__repr__()) return TagArtist().draw(self.binary_12)