Module rpps.dobject

Containers for data to ensure we can track where it came from

Functions

def ensure_bit(dobj)

Ensure DataObject is using bits

def ensure_byte(dobj)

Ensure DataObject is using bytes

Classes

class BitObject (data=None, meta=None)

Parent DataObject class

Expand source code
class BitObject(DataObject):
    type = Type.BIT
    data = np.array([], dtype=bool)

    def __str__(self):
        return f"{super().__str__()}:{self.bin}"

    @property
    def bin(self):
        return self.data.astype(int)

Ancestors

Subclasses

Class variables

var data
var type

Instance variables

prop bin
Expand source code
@property
def bin(self):
    return self.data.astype(int)

Inherited members

class ByteObject (data=None, meta=None)

Parent DataObject class

Expand source code
class ByteObject(DataObject):
    type = Type.BYTE
    data = np.array([], dtype=np.uint8)

    def __str__(self):
        return f"{super().__str__()}:{self.hex}"

    @property
    def hex(self):
        return self.data.tobytes().hex()

Ancestors

Subclasses

Class variables

var data
var type

Instance variables

prop hex
Expand source code
@property
def hex(self):
    return self.data.tobytes().hex()

Inherited members

class CodingData (data=None, meta=None)

Data post-coding

Expand source code
class CodingData(BitObject):
    """Data post-coding"""

Ancestors

Inherited members

class DataObject (data=None, meta=None)

Parent DataObject class

Expand source code
class DataObject:
    """Parent DataObject class"""
    type = Type.NONE

    data = []
    meta = None

    def __init__(self, data=None, meta=None):
        if not isinstance(meta, Meta):
            meta = Meta()
        self.convert(data)
        self.meta = meta

    def __str__(self):
        return f"{self.name()}:{self.type}:{len(self)}"

    def __repr__(self):
        return str(self)

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

    def __enter__(self, *args, **kwargs):
        return self.data.__enter__(*args, **kwargs) # type: ignore

    def __exit__(self, *args, **kwargs):
        return self.data.__exit__(*args, **kwargs) # type: ignore

    def __iter__(self, *args, **kwargs):
        return self.data.__iter__(*args, **kwargs)

    def __getitem__(self, *args, **kwargs):
        return self.data.__getitem__(*args, **kwargs)

    def name(self):
        """Get class name"""
        return type(self).__name__

    def append(self, data):
        self.data = np.append(self.data, data)

    def to_bits(self):
        if isinstance(self.data, np.ndarray):
            if self.type == Type.BIT:
                return self.data
            elif self.type == Type.BYTE:
                return np.unpackbits(self.data)
        raise NotImplementedError(f"Cannot convert {self.type} to bits")

    def to_bytes(self):
        if isinstance(self.data, np.ndarray):
            if self.type == Type.BYTE:
                return self.data
            if self.type == Type.BIT:
                return np.packbits(self.data)
        raise NotImplementedError(f"Cannot convert {self.type} to bytes")

    def convert(self, other):
        """Convert other to self"""
        if issubclass(type(other), DataObject):
            if self.type == Type.BIT:
                self.data = other.to_bits()
                return
            elif self.type == Type.BYTE:
                self.data = other.to_bytes()
                return
            raise NotImplementedError(f"Cannot convert {other.type} to {self.type}")
        else:
            if other is None:
                if self.type == Type.BYTE:
                    self.data = np.array([], dtype=np.uint8)
                    return
                elif self.type == Type.BIT:
                    self.data = np.array([], dtype=bool)
                    return
            elif isinstance(other, bytes):
                if self.type == Type.BYTE:
                    self.data = np.frombuffer(other, dtype=np.uint8)
                    return
                elif self.type == Type.BIT:
                    self.data = np.unpackbits(np.array(other))
                    return
            elif isinstance(other, np.ndarray):
                if self.type == Type.SYM:
                    self.data = other
                    return
                if other.dtype == np.uint8:
                    if self.type == Type.BYTE:
                        self.data = np.copy(other)
                        return
                    elif self.type == Type.BIT:
                        self.data = np.unpackbits(other)
                        return
                elif other.dtype == bool:
                    if self.type == Type.BYTE:
                        self.data = np.packbits(other)
                        return
                    elif self.type == Type.BIT:
                        self.data = np.copy(other)
                        return
                raise NotImplementedError(f"Cannot convert {type(other)} {other.shape} {other.dtype} to {self.type}")

        raise NotImplementedError(f"Cannot convert {type(other)} to {self.type}")

Subclasses

Class variables

var data
var meta
var type

Methods

def append(self, data)
def convert(self, other)

Convert other to self

def name(self)

Get class name

def to_bits(self)
def to_bytes(self)
class ModData (data=None, meta=None)

Data returned from mod.demodulate

Expand source code
class ModData(BitObject):
    """Data returned from mod.demodulate"""
    soft = SoftDecision()
    _data = None

    @property
    def hard(self):
        return self.soft.hard()

    @property
    def data(self):
        if self._data is not None:
            return self._data
        return self.soft.bits

    @data.setter
    def data(self, value):
        self._data = value

Ancestors

Class variables

var soft

Instance variables

prop data

ndarray(shape, dtype=float, buffer=None, offset=0, strides=None, order=None)

An array object represents a multidimensional, homogeneous array of fixed-size items. An associated data-type object describes the format of each element in the array (its byte-order, how many bytes it occupies in memory, whether it is an integer, a floating point number, or something else, etc.)

Arrays should be constructed using array, zeros or empty (refer to the See Also section below). The parameters given here refer to a low-level method (ndarray(…)) for instantiating an array.

For more information, refer to the numpy module and examine the methods and attributes of an array.

Parameters

(for the new method; see Notes below)

shape : tuple of ints
Shape of created array.
dtype : data-type, optional
Any object that can be interpreted as a numpy data type.
buffer : object exposing buffer interface, optional
Used to fill the array with data.
offset : int, optional
Offset of array data in buffer.
strides : tuple of ints, optional
Strides of data in memory.
order : {'C', 'F'}, optional
Row-major (C-style) or column-major (Fortran-style) order.

Attributes

T : ndarray
Transpose of the array.
data : buffer
The array's elements, in memory.
dtype : dtype object
Describes the format of the elements in the array.
flags : dict
Dictionary containing information related to memory use, e.g., 'C_CONTIGUOUS', 'OWNDATA', 'WRITEABLE', etc.
flat : numpy.flatiter object
Flattened version of the array as an iterator. The iterator allows assignments, e.g., x.flat = 3 (See ndarray.flat for assignment examples; TODO).
imag : ndarray
Imaginary part of the array.
real : ndarray
Real part of the array.
size : int
Number of elements in the array.
itemsize : int
The memory use of each array element in bytes.
nbytes : int
The total number of bytes required to store the array data, i.e., itemsize * size.
ndim : int
The array's number of dimensions.
shape : tuple of ints
Shape of the array.
strides : tuple of ints
The step-size required to move from one element to the next in memory. For example, a contiguous (3, 4) array of type int16 in C-order has strides (8, 2). This implies that to move from element to element in memory requires jumps of 2 bytes. To move from row-to-row, one needs to jump 8 bytes at a time (2 * 4).
ctypes : ctypes object
Class containing properties of the array needed for interaction with ctypes.
base : ndarray
If the array is a view into another array, that array is its base (unless that array is also a view). The base array is where the array data is actually stored.

See Also

array
Construct an array.
zeros
Create an array, each element of which is zero.
empty
Create an array, but leave its allocated memory unchanged (i.e., it contains "garbage").
dtype
Create a data-type.
numpy.typing.NDArray
An ndarray alias :term:generic <generic type> w.r.t. its dtype.type <numpy.dtype.type>.

Notes

There are two modes of creating an array using __new__:

  1. If buffer is None, then only shape, dtype, and order are used.
  2. If buffer is an object exposing the buffer interface, then all keywords are interpreted.

No __init__ method is needed because the array is fully initialized after the __new__ method.

Examples

These examples illustrate the low-level ndarray constructor. Refer to the See Also section above for easier ways of constructing an ndarray.

First mode, buffer is None:

>>> np.ndarray(shape=(2,2), dtype=float, order='F')
array([[0.0e+000, 0.0e+000], # random
       [     nan, 2.5e-323]])

Second mode:

>>> np.ndarray((2,), buffer=np.array([1,2,3]),
...            offset=np.int_().itemsize,
...            dtype=int) # offset = 1*itemsize, i.e. skip first element
array([2, 3])
Expand source code
@property
def data(self):
    if self._data is not None:
        return self._data
    return self.soft.bits
prop hard
Expand source code
@property
def hard(self):
    return self.soft.hard()

Inherited members

class ScramData (data=None, meta=None)

Data post-scrambler

Expand source code
class ScramData(BitObject):
    """Data post-scrambler"""

Ancestors

Inherited members

class StreamData (data=None, meta=None)

Raw input/output data

Expand source code
class StreamData(ByteObject):
    """Raw input/output data"""

Ancestors

Inherited members

class SymData (data=None, meta=None)

Data returned from mod.modulate

Expand source code
class SymData(SymObject):
    """Data returned from mod.modulate"""

Ancestors

Inherited members

class SymObject (data=None, meta=None)

Parent DataObject class

Expand source code
class SymObject(DataObject):
    type = Type.SYM

    def __str__(self):
        return f"{super().__str__()} syms"

Ancestors

Subclasses

Class variables

var type

Inherited members

class Type (*args, **kwds)

DataObject data data formats

Expand source code
class Type(Enum):
    """DataObject data data formats"""
    BIT = 0
    BYTE = 1
    SYM = 2
    NONE = -1

Ancestors

  • enum.Enum

Class variables

var BIT
var BYTE
var NONE
var SYM