Module c3d.group
Classes used to represent the concept of parameter groups in a .c3d file.
Expand source code
''' Classes used to represent the concept of parameter groups in a .c3d file.
'''
import struct
import numpy as np
from .parameter import ParamData, Param
from .utils import Decorator
class GroupData(object):
'''A group of parameters stored in a C3D file.
In C3D files, parameters are organized in groups. Each group has a name (key), a
description, and a set of named parameters. Each group is also internally associated
with a numeric key.
Attributes
----------
dtypes : `c3d.dtypes.DataTypes`
Data types object used for parsing.
name : str
Name of this parameter group.
desc : str
Description for this parameter group.
'''
def __init__(self, dtypes, name=None, desc=None):
self._params = {}
self._dtypes = dtypes
# Assign through property setters
self.set_name(name)
self.set_desc(desc)
def __repr__(self):
return '<Group: {}>'.format(self.desc)
def __contains__(self, key):
return key in self._params
def __getitem__(self, key):
return self._params[key]
@property
def binary_size(self) -> int:
'''Return the number of bytes to store this group and its parameters.'''
return (
1 + # group_id
1 + len(self.name.encode('utf-8')) + # size of name and name bytes
2 + # next offset marker
1 + len(self.desc.encode('utf-8')) + # size of desc and desc bytes
sum(p.binary_size for p in self._params.values()))
def set_name(self, name):
''' Set the group name string. '''
if name is None or isinstance(name, str):
self.name = name
else:
raise TypeError('Expected group name to be string, was %s.' % type(name))
def set_desc(self, desc):
''' Set the Group descriptor.
'''
if isinstance(desc, bytes):
self.desc = self._dtypes.decode_string(desc)
elif isinstance(desc, str) or desc is None:
self.desc = desc
else:
raise TypeError('Expected descriptor to be python string, bytes or None, was %s.' % type(desc))
def add_param(self, name, **kwargs):
'''Add a parameter to this group.
Parameters
----------
name : str
Name of the parameter to add to this group. The name will
automatically be case-normalized.
See constructor of `c3d.parameter.ParamData` for additional keyword arguments.
Raises
------
TypeError
Input arguments are of the wrong type.
KeyError
Name or numerical key already exist (attempt to overwrite existing data).
'''
if not isinstance(name, str):
raise TypeError("Expected 'name' argument to be a string, was of type {}".format(type(name)))
name = name.upper()
if name in self._params:
raise KeyError('Parameter already exists with key {}'.format(name))
self._params[name] = Param(ParamData(name, self._dtypes, **kwargs))
def remove_param(self, name):
'''Remove the specified parameter.
Parameters
----------
name : str
Name for the parameter to remove.
'''
del self._params[name]
def rename_param(self, name, new_name):
''' Rename a specified parameter group.
Parameters
----------
name : str, or `c3d.group.GroupReadonly`
Parameter instance, or name.
new_name : str
New name for the parameter.
Raises
------
KeyError
If no parameter with the original name exists.
ValueError
If the new name already exist (attempt to overwrite existing data).
'''
if new_name in self._params:
raise ValueError("Key {} already exist.".format(new_name))
if isinstance(name, Param):
param = name
name = param.name
else:
# Aquire instance using id
param = self._params[name]
del self._params[name]
self._params[new_name] = param
def write(self, group_id, handle):
'''Write this parameter group, with parameters, to a file handle.
Parameters
----------
group_id : int
The numerical ID of the group.
handle : file handle
An open, writable, binary file handle.
'''
name = self.name.encode('utf-8')
desc = self.desc.encode('utf-8')
handle.write(struct.pack('bb', len(name), -group_id))
handle.write(name)
handle.write(struct.pack('<h', 3 + len(desc)))
handle.write(struct.pack('B', len(desc)))
handle.write(desc)
for param in self._params.values():
param._data.write(group_id, handle)
class GroupReadonly(object):
''' Wrapper exposing readonly attributes of a `c3d.group.GroupData` entry.
'''
def __init__(self, data):
self._data = data
def __contains__(self, key):
return key in self._data._params
def __eq__(self, other):
return self._data is other._data
@property
def name(self) -> str:
''' Access group name. '''
return self._data.name
@property
def desc(self) -> str:
'''Access group descriptor. '''
return self._data.desc
def items(self):
''' Get iterator for paramater key-entry pairs. '''
return ((k, v.readonly()) for k, v in self._data._params.items())
def values(self):
''' Get iterator for parameter entries. '''
return (v.readonly() for v in self._data._params.values())
def keys(self):
''' Get iterator for parameter entry keys. '''
return self._data._params.keys()
def get(self, key, default=None):
'''Get a readonly parameter by key.
Parameters
----------
key : any
Parameter key to look up in this group.
default : any, optional
Value to return if the key is not found. Defaults to None.
Returns
-------
param : :class:`ParamReadable`
A parameter from the current group.
'''
val = self._data._params.get(key, default)
if val:
return val.readonly()
return default
def get_int8(self, key):
'''Get the value of the given parameter as an 8-bit signed integer.'''
return self._data[key.upper()].int8_value
def get_uint8(self, key):
'''Get the value of the given parameter as an 8-bit unsigned integer.'''
return self._data[key.upper()].uint8_value
def get_int16(self, key):
'''Get the value of the given parameter as a 16-bit signed integer.'''
return self._data[key.upper()].int16_value
def get_uint16(self, key):
'''Get the value of the given parameter as a 16-bit unsigned integer.'''
return self._data[key.upper()].uint16_value
def get_int32(self, key):
'''Get the value of the given parameter as a 32-bit signed integer.'''
return self._data[key.upper()].int32_value
def get_uint32(self, key):
'''Get the value of the given parameter as a 32-bit unsigned integer.'''
return self._data[key.upper()].uint32_value
def get_float(self, key):
'''Get the value of the given parameter as a 32-bit float.'''
return self._data[key.upper()].float_value
def get_bytes(self, key):
'''Get the value of the given parameter as a byte array.'''
return self._data[key.upper()].bytes_value
def get_string(self, key):
'''Get the value of the given parameter as a string.'''
return self._data[key.upper()].string_value
class Group(GroupReadonly):
''' Wrapper exposing readable and writeable attributes of a `c3d.group.GroupData` entry.
'''
def __init__(self, data):
super(Group, self).__init__(data)
def readonly(self):
''' Returns a `c3d.group.GroupReadonly` instance with readonly access. '''
return GroupReadonly(self._data)
@property
def name(self) -> str:
''' Get or set name. '''
return self._data.name
@name.setter
def name(self, value) -> str:
self._data.set_name(value)
@property
def desc(self) -> str:
''' Get or set descriptor. '''
return self._data.desc
@desc.setter
def desc(self, value) -> str:
self._data.set_desc(value)
def items(self):
''' Iterator for paramater key-entry pairs. '''
return ((k, v) for k, v in self._data._params.items())
def values(self):
''' Iterator iterator for parameter entries. '''
return (v for v in self._data._params.values())
def get(self, key, default=None):
'''Get a parameter by key.
Parameters
----------
key : any
Parameter key to look up in this group.
default : any, optional
Value to return if the key is not found. Defaults to None.
Returns
-------
param : :class:`ParamReadable`
A parameter from the current group.
'''
return self._data._params.get(key, default)
#
# Forward param editing
#
def add_param(self, name, **kwargs):
'''Add a parameter to this group.
See constructor of `c3d.parameter.ParamData` for additional keyword arguments.
'''
self._data.add_param(name, **kwargs)
def remove_param(self, name):
'''Remove the specified parameter.
Parameters
----------
name : str
Name for the parameter to remove.
'''
self._data.remove_param(name)
def rename_param(self, name, new_name):
''' Rename a specified parameter group.
Parameters
----------
See arguments in `c3d.group.GroupData.rename_param`.
'''
self._data.rename_param(name, new_name)
#
# Convenience functions for adding parameters.
#
def add(self, name, desc, bpe, format, data, *dimensions):
''' Add a parameter with `data` package formated in accordance with `format`.
Convenience function for `c3d.group.GroupData.add_param` calling struct.pack() on `data`.
Example:
>>> group.set('RATE', 'Point data sample rate', 4, '<f', 100)
Parameters
----------
name : str
Parameter name.
desc : str
Parameter descriptor.
bpe : int
Number of bytes for each atomic element.
format : str or None
`struct.format()` compatible format string see:
https://docs.python.org/3/library/struct.html#format-characters
*dimensions : int, optional
Shape associated with the data (if the data argument represents multiple elements).
'''
if isinstance(data, bytes):
pass
else:
data = struct.pack(format, data)
self.add_param(name,
desc=desc,
bytes_per_element=bpe,
bytes=data,
dimensions=list(dimensions))
def add_array(self, name, desc, data, dtype=None):
'''Add a parameter with the `data` package.
Parameters
----------
name : str
Parameter name.
desc : str
Parameter descriptor.
data : np.ndarray, or iterable
Data array to encode in the parameter.
dtype : np.dtype, optional
Numpy data type used to encode the array (optional only if `data.dtype` returns a numpy type).
'''
if not isinstance(data, np.ndarray):
if dtype is None:
dtype = data.dtype
data = np.array(data, dtype=dtype)
elif dtype is None:
dtype = data.dtype
self.add_param(name,
desc=desc,
bytes_per_element=dtype.itemsize,
bytes=data.tobytes(),
dimensions=data.shape[::-1])
def add_str(self, name, desc, data, *dimensions):
''' Add a string parameter.
Parameters
----------
name : str
Parameter name.
desc : str
Parameter descriptor.
data : str
String to encode in the parameter.
*dimensions : int, optional
Shape associated with the string (if the string represents multiple elements).
'''
shape = list(dimensions)
self.add_param(name,
desc=desc,
bytes_per_element=-1,
bytes=data.encode('utf-8'),
dimensions=shape or [len(data)])
def add_empty_array(self, name, desc=''):
''' Add an empty parameter block.
Parameters
----------
name : str
Parameter name.
'''
self.add_param(name, desc=desc,
bytes_per_element=0, dimensions=[0])
#
# Convenience functions for adding or overwriting parameters.
#
def set(self, name, *args, **kwargs):
''' Add or overwrite a parameter with 'bytes' package formated in accordance with 'format'.
See arguments in `c3d.group.Group.add`.
'''
try:
self.remove_param(name)
except KeyError as e:
pass
self.add(name, *args, **kwargs)
def set_str(self, name, *args, **kwargs):
''' Add or overwrite a string parameter.
See arguments in `c3d.group.Group.add_str`.
'''
try:
self.remove_param(name)
except KeyError as e:
pass
self.add_str(name, *args, **kwargs)
def set_array(self, name, *args, **kwargs):
''' Add or overwrite a parameter with the `data` package.
See arguments in `c3d.group.Group.add_array`.
'''
try:
self.remove_param(name)
except KeyError as e:
pass
self.add_array(name, *args, **kwargs)
def set_empty_array(self, name, *args, **kwargs):
''' Add an empty parameter block.
See arguments in `c3d.group.Group.add_empty_array`.
'''
try:
self.remove_param(name)
except KeyError as e:
pass
self.add_empty_array(name, *args, **kwargs)
Classes
class Group (data)
-
Wrapper exposing readable and writeable attributes of a
GroupData
entry.Expand source code
class Group(GroupReadonly): ''' Wrapper exposing readable and writeable attributes of a `c3d.group.GroupData` entry. ''' def __init__(self, data): super(Group, self).__init__(data) def readonly(self): ''' Returns a `c3d.group.GroupReadonly` instance with readonly access. ''' return GroupReadonly(self._data) @property def name(self) -> str: ''' Get or set name. ''' return self._data.name @name.setter def name(self, value) -> str: self._data.set_name(value) @property def desc(self) -> str: ''' Get or set descriptor. ''' return self._data.desc @desc.setter def desc(self, value) -> str: self._data.set_desc(value) def items(self): ''' Iterator for paramater key-entry pairs. ''' return ((k, v) for k, v in self._data._params.items()) def values(self): ''' Iterator iterator for parameter entries. ''' return (v for v in self._data._params.values()) def get(self, key, default=None): '''Get a parameter by key. Parameters ---------- key : any Parameter key to look up in this group. default : any, optional Value to return if the key is not found. Defaults to None. Returns ------- param : :class:`ParamReadable` A parameter from the current group. ''' return self._data._params.get(key, default) # # Forward param editing # def add_param(self, name, **kwargs): '''Add a parameter to this group. See constructor of `c3d.parameter.ParamData` for additional keyword arguments. ''' self._data.add_param(name, **kwargs) def remove_param(self, name): '''Remove the specified parameter. Parameters ---------- name : str Name for the parameter to remove. ''' self._data.remove_param(name) def rename_param(self, name, new_name): ''' Rename a specified parameter group. Parameters ---------- See arguments in `c3d.group.GroupData.rename_param`. ''' self._data.rename_param(name, new_name) # # Convenience functions for adding parameters. # def add(self, name, desc, bpe, format, data, *dimensions): ''' Add a parameter with `data` package formated in accordance with `format`. Convenience function for `c3d.group.GroupData.add_param` calling struct.pack() on `data`. Example: >>> group.set('RATE', 'Point data sample rate', 4, '<f', 100) Parameters ---------- name : str Parameter name. desc : str Parameter descriptor. bpe : int Number of bytes for each atomic element. format : str or None `struct.format()` compatible format string see: https://docs.python.org/3/library/struct.html#format-characters *dimensions : int, optional Shape associated with the data (if the data argument represents multiple elements). ''' if isinstance(data, bytes): pass else: data = struct.pack(format, data) self.add_param(name, desc=desc, bytes_per_element=bpe, bytes=data, dimensions=list(dimensions)) def add_array(self, name, desc, data, dtype=None): '''Add a parameter with the `data` package. Parameters ---------- name : str Parameter name. desc : str Parameter descriptor. data : np.ndarray, or iterable Data array to encode in the parameter. dtype : np.dtype, optional Numpy data type used to encode the array (optional only if `data.dtype` returns a numpy type). ''' if not isinstance(data, np.ndarray): if dtype is None: dtype = data.dtype data = np.array(data, dtype=dtype) elif dtype is None: dtype = data.dtype self.add_param(name, desc=desc, bytes_per_element=dtype.itemsize, bytes=data.tobytes(), dimensions=data.shape[::-1]) def add_str(self, name, desc, data, *dimensions): ''' Add a string parameter. Parameters ---------- name : str Parameter name. desc : str Parameter descriptor. data : str String to encode in the parameter. *dimensions : int, optional Shape associated with the string (if the string represents multiple elements). ''' shape = list(dimensions) self.add_param(name, desc=desc, bytes_per_element=-1, bytes=data.encode('utf-8'), dimensions=shape or [len(data)]) def add_empty_array(self, name, desc=''): ''' Add an empty parameter block. Parameters ---------- name : str Parameter name. ''' self.add_param(name, desc=desc, bytes_per_element=0, dimensions=[0]) # # Convenience functions for adding or overwriting parameters. # def set(self, name, *args, **kwargs): ''' Add or overwrite a parameter with 'bytes' package formated in accordance with 'format'. See arguments in `c3d.group.Group.add`. ''' try: self.remove_param(name) except KeyError as e: pass self.add(name, *args, **kwargs) def set_str(self, name, *args, **kwargs): ''' Add or overwrite a string parameter. See arguments in `c3d.group.Group.add_str`. ''' try: self.remove_param(name) except KeyError as e: pass self.add_str(name, *args, **kwargs) def set_array(self, name, *args, **kwargs): ''' Add or overwrite a parameter with the `data` package. See arguments in `c3d.group.Group.add_array`. ''' try: self.remove_param(name) except KeyError as e: pass self.add_array(name, *args, **kwargs) def set_empty_array(self, name, *args, **kwargs): ''' Add an empty parameter block. See arguments in `c3d.group.Group.add_empty_array`. ''' try: self.remove_param(name) except KeyError as e: pass self.add_empty_array(name, *args, **kwargs)
Ancestors
Instance variables
var desc : str
-
Get or set descriptor.
Expand source code
@property def desc(self) -> str: ''' Get or set descriptor. ''' return self._data.desc
var name : str
-
Get or set name.
Expand source code
@property def name(self) -> str: ''' Get or set name. ''' return self._data.name
Methods
def add(self, name, desc, bpe, format, data, *dimensions)
-
Add a parameter with
data
package formated in accordance withformat
.Convenience function for
GroupData.add_param()
calling struct.pack() ondata
.Example:
>>> group.set('RATE', 'Point data sample rate', 4, '<f', 100)
Parameters
name
:str
- Parameter name.
desc
:str
- Parameter descriptor.
bpe
:int
- Number of bytes for each atomic element.
format
:str
orNone
struct.format()
compatible format string see: https://docs.python.org/3/library/struct.html#format-characters*dimensions
:int
, optional- Shape associated with the data (if the data argument represents multiple elements).
Expand source code
def add(self, name, desc, bpe, format, data, *dimensions): ''' Add a parameter with `data` package formated in accordance with `format`. Convenience function for `c3d.group.GroupData.add_param` calling struct.pack() on `data`. Example: >>> group.set('RATE', 'Point data sample rate', 4, '<f', 100) Parameters ---------- name : str Parameter name. desc : str Parameter descriptor. bpe : int Number of bytes for each atomic element. format : str or None `struct.format()` compatible format string see: https://docs.python.org/3/library/struct.html#format-characters *dimensions : int, optional Shape associated with the data (if the data argument represents multiple elements). ''' if isinstance(data, bytes): pass else: data = struct.pack(format, data) self.add_param(name, desc=desc, bytes_per_element=bpe, bytes=data, dimensions=list(dimensions))
def add_array(self, name, desc, data, dtype=None)
-
Add a parameter with the
data
package.Parameters
name
:str
- Parameter name.
desc
:str
- Parameter descriptor.
data
:np.ndarray,
oriterable
- Data array to encode in the parameter.
dtype
:np.dtype
, optional- Numpy data type used to encode the array (optional only if
data.dtype
returns a numpy type).
Expand source code
def add_array(self, name, desc, data, dtype=None): '''Add a parameter with the `data` package. Parameters ---------- name : str Parameter name. desc : str Parameter descriptor. data : np.ndarray, or iterable Data array to encode in the parameter. dtype : np.dtype, optional Numpy data type used to encode the array (optional only if `data.dtype` returns a numpy type). ''' if not isinstance(data, np.ndarray): if dtype is None: dtype = data.dtype data = np.array(data, dtype=dtype) elif dtype is None: dtype = data.dtype self.add_param(name, desc=desc, bytes_per_element=dtype.itemsize, bytes=data.tobytes(), dimensions=data.shape[::-1])
def add_empty_array(self, name, desc='')
-
Add an empty parameter block.
Parameters
name
:str
- Parameter name.
Expand source code
def add_empty_array(self, name, desc=''): ''' Add an empty parameter block. Parameters ---------- name : str Parameter name. ''' self.add_param(name, desc=desc, bytes_per_element=0, dimensions=[0])
def add_param(self, name, **kwargs)
-
Add a parameter to this group.
See constructor of
ParamData
for additional keyword arguments.Expand source code
def add_param(self, name, **kwargs): '''Add a parameter to this group. See constructor of `c3d.parameter.ParamData` for additional keyword arguments. ''' self._data.add_param(name, **kwargs)
def add_str(self, name, desc, data, *dimensions)
-
Add a string parameter.
Parameters
name
:str
- Parameter name.
desc
:str
- Parameter descriptor.
data
:str
- String to encode in the parameter.
*dimensions
:int
, optional- Shape associated with the string (if the string represents multiple elements).
Expand source code
def add_str(self, name, desc, data, *dimensions): ''' Add a string parameter. Parameters ---------- name : str Parameter name. desc : str Parameter descriptor. data : str String to encode in the parameter. *dimensions : int, optional Shape associated with the string (if the string represents multiple elements). ''' shape = list(dimensions) self.add_param(name, desc=desc, bytes_per_element=-1, bytes=data.encode('utf-8'), dimensions=shape or [len(data)])
def get(self, key, default=None)
-
Get a parameter by key.
Parameters
key
:any
- Parameter key to look up in this group.
default
:any
, optional- Value to return if the key is not found. Defaults to None.
Returns
param
::class:
ParamReadable``- A parameter from the current group.
Expand source code
def get(self, key, default=None): '''Get a parameter by key. Parameters ---------- key : any Parameter key to look up in this group. default : any, optional Value to return if the key is not found. Defaults to None. Returns ------- param : :class:`ParamReadable` A parameter from the current group. ''' return self._data._params.get(key, default)
def items(self)
-
Iterator for paramater key-entry pairs.
Expand source code
def items(self): ''' Iterator for paramater key-entry pairs. ''' return ((k, v) for k, v in self._data._params.items())
def readonly(self)
-
Returns a
GroupReadonly
instance with readonly access.Expand source code
def readonly(self): ''' Returns a `c3d.group.GroupReadonly` instance with readonly access. ''' return GroupReadonly(self._data)
def remove_param(self, name)
-
Remove the specified parameter.
Parameters
name
:str
- Name for the parameter to remove.
Expand source code
def remove_param(self, name): '''Remove the specified parameter. Parameters ---------- name : str Name for the parameter to remove. ''' self._data.remove_param(name)
def rename_param(self, name, new_name)
-
Expand source code
def rename_param(self, name, new_name): ''' Rename a specified parameter group. Parameters ---------- See arguments in `c3d.group.GroupData.rename_param`. ''' self._data.rename_param(name, new_name)
def set(self, name, *args, **kwargs)
-
Add or overwrite a parameter with 'bytes' package formated in accordance with 'format'.
See arguments in
Group.add()
.Expand source code
def set(self, name, *args, **kwargs): ''' Add or overwrite a parameter with 'bytes' package formated in accordance with 'format'. See arguments in `c3d.group.Group.add`. ''' try: self.remove_param(name) except KeyError as e: pass self.add(name, *args, **kwargs)
def set_array(self, name, *args, **kwargs)
-
Add or overwrite a parameter with the
data
package.See arguments in
Group.add_array()
.Expand source code
def set_array(self, name, *args, **kwargs): ''' Add or overwrite a parameter with the `data` package. See arguments in `c3d.group.Group.add_array`. ''' try: self.remove_param(name) except KeyError as e: pass self.add_array(name, *args, **kwargs)
def set_empty_array(self, name, *args, **kwargs)
-
Add an empty parameter block.
See arguments in
Group.add_empty_array()
.Expand source code
def set_empty_array(self, name, *args, **kwargs): ''' Add an empty parameter block. See arguments in `c3d.group.Group.add_empty_array`. ''' try: self.remove_param(name) except KeyError as e: pass self.add_empty_array(name, *args, **kwargs)
def set_str(self, name, *args, **kwargs)
-
Add or overwrite a string parameter.
See arguments in
Group.add_str()
.Expand source code
def set_str(self, name, *args, **kwargs): ''' Add or overwrite a string parameter. See arguments in `c3d.group.Group.add_str`. ''' try: self.remove_param(name) except KeyError as e: pass self.add_str(name, *args, **kwargs)
def values(self)
-
Iterator iterator for parameter entries.
Expand source code
def values(self): ''' Iterator iterator for parameter entries. ''' return (v for v in self._data._params.values())
Inherited members
class GroupData (dtypes, name=None, desc=None)
-
A group of parameters stored in a C3D file.
In C3D files, parameters are organized in groups. Each group has a name (key), a description, and a set of named parameters. Each group is also internally associated with a numeric key.
Attributes
dtypes
:DataTypes
- Data types object used for parsing.
name
:str
- Name of this parameter group.
desc
:str
- Description for this parameter group.
Expand source code
class GroupData(object): '''A group of parameters stored in a C3D file. In C3D files, parameters are organized in groups. Each group has a name (key), a description, and a set of named parameters. Each group is also internally associated with a numeric key. Attributes ---------- dtypes : `c3d.dtypes.DataTypes` Data types object used for parsing. name : str Name of this parameter group. desc : str Description for this parameter group. ''' def __init__(self, dtypes, name=None, desc=None): self._params = {} self._dtypes = dtypes # Assign through property setters self.set_name(name) self.set_desc(desc) def __repr__(self): return '<Group: {}>'.format(self.desc) def __contains__(self, key): return key in self._params def __getitem__(self, key): return self._params[key] @property def binary_size(self) -> int: '''Return the number of bytes to store this group and its parameters.''' return ( 1 + # group_id 1 + len(self.name.encode('utf-8')) + # size of name and name bytes 2 + # next offset marker 1 + len(self.desc.encode('utf-8')) + # size of desc and desc bytes sum(p.binary_size for p in self._params.values())) def set_name(self, name): ''' Set the group name string. ''' if name is None or isinstance(name, str): self.name = name else: raise TypeError('Expected group name to be string, was %s.' % type(name)) def set_desc(self, desc): ''' Set the Group descriptor. ''' if isinstance(desc, bytes): self.desc = self._dtypes.decode_string(desc) elif isinstance(desc, str) or desc is None: self.desc = desc else: raise TypeError('Expected descriptor to be python string, bytes or None, was %s.' % type(desc)) def add_param(self, name, **kwargs): '''Add a parameter to this group. Parameters ---------- name : str Name of the parameter to add to this group. The name will automatically be case-normalized. See constructor of `c3d.parameter.ParamData` for additional keyword arguments. Raises ------ TypeError Input arguments are of the wrong type. KeyError Name or numerical key already exist (attempt to overwrite existing data). ''' if not isinstance(name, str): raise TypeError("Expected 'name' argument to be a string, was of type {}".format(type(name))) name = name.upper() if name in self._params: raise KeyError('Parameter already exists with key {}'.format(name)) self._params[name] = Param(ParamData(name, self._dtypes, **kwargs)) def remove_param(self, name): '''Remove the specified parameter. Parameters ---------- name : str Name for the parameter to remove. ''' del self._params[name] def rename_param(self, name, new_name): ''' Rename a specified parameter group. Parameters ---------- name : str, or `c3d.group.GroupReadonly` Parameter instance, or name. new_name : str New name for the parameter. Raises ------ KeyError If no parameter with the original name exists. ValueError If the new name already exist (attempt to overwrite existing data). ''' if new_name in self._params: raise ValueError("Key {} already exist.".format(new_name)) if isinstance(name, Param): param = name name = param.name else: # Aquire instance using id param = self._params[name] del self._params[name] self._params[new_name] = param def write(self, group_id, handle): '''Write this parameter group, with parameters, to a file handle. Parameters ---------- group_id : int The numerical ID of the group. handle : file handle An open, writable, binary file handle. ''' name = self.name.encode('utf-8') desc = self.desc.encode('utf-8') handle.write(struct.pack('bb', len(name), -group_id)) handle.write(name) handle.write(struct.pack('<h', 3 + len(desc))) handle.write(struct.pack('B', len(desc))) handle.write(desc) for param in self._params.values(): param._data.write(group_id, handle)
Instance variables
var binary_size : int
-
Return the number of bytes to store this group and its parameters.
Expand source code
@property def binary_size(self) -> int: '''Return the number of bytes to store this group and its parameters.''' return ( 1 + # group_id 1 + len(self.name.encode('utf-8')) + # size of name and name bytes 2 + # next offset marker 1 + len(self.desc.encode('utf-8')) + # size of desc and desc bytes sum(p.binary_size for p in self._params.values()))
Methods
def add_param(self, name, **kwargs)
-
Add a parameter to this group.
Parameters
name
:str
- Name of the parameter to add to this group. The name will automatically be case-normalized.
See constructor of
ParamData
for additional keyword arguments.Raises
TypeError
- Input arguments are of the wrong type.
KeyError
- Name or numerical key already exist (attempt to overwrite existing data).
Expand source code
def add_param(self, name, **kwargs): '''Add a parameter to this group. Parameters ---------- name : str Name of the parameter to add to this group. The name will automatically be case-normalized. See constructor of `c3d.parameter.ParamData` for additional keyword arguments. Raises ------ TypeError Input arguments are of the wrong type. KeyError Name or numerical key already exist (attempt to overwrite existing data). ''' if not isinstance(name, str): raise TypeError("Expected 'name' argument to be a string, was of type {}".format(type(name))) name = name.upper() if name in self._params: raise KeyError('Parameter already exists with key {}'.format(name)) self._params[name] = Param(ParamData(name, self._dtypes, **kwargs))
def remove_param(self, name)
-
Remove the specified parameter.
Parameters
name
:str
- Name for the parameter to remove.
Expand source code
def remove_param(self, name): '''Remove the specified parameter. Parameters ---------- name : str Name for the parameter to remove. ''' del self._params[name]
def rename_param(self, name, new_name)
-
Rename a specified parameter group.
Parameters
name
:str,
orGroupReadonly
- Parameter instance, or name.
new_name
:str
- New name for the parameter.
Raises
KeyError
- If no parameter with the original name exists.
ValueError
- If the new name already exist (attempt to overwrite existing data).
Expand source code
def rename_param(self, name, new_name): ''' Rename a specified parameter group. Parameters ---------- name : str, or `c3d.group.GroupReadonly` Parameter instance, or name. new_name : str New name for the parameter. Raises ------ KeyError If no parameter with the original name exists. ValueError If the new name already exist (attempt to overwrite existing data). ''' if new_name in self._params: raise ValueError("Key {} already exist.".format(new_name)) if isinstance(name, Param): param = name name = param.name else: # Aquire instance using id param = self._params[name] del self._params[name] self._params[new_name] = param
def set_desc(self, desc)
-
Set the Group descriptor.
Expand source code
def set_desc(self, desc): ''' Set the Group descriptor. ''' if isinstance(desc, bytes): self.desc = self._dtypes.decode_string(desc) elif isinstance(desc, str) or desc is None: self.desc = desc else: raise TypeError('Expected descriptor to be python string, bytes or None, was %s.' % type(desc))
def set_name(self, name)
-
Set the group name string.
Expand source code
def set_name(self, name): ''' Set the group name string. ''' if name is None or isinstance(name, str): self.name = name else: raise TypeError('Expected group name to be string, was %s.' % type(name))
def write(self, group_id, handle)
-
Write this parameter group, with parameters, to a file handle.
Parameters
group_id
:int
- The numerical ID of the group.
handle
:file handle
- An open, writable, binary file handle.
Expand source code
def write(self, group_id, handle): '''Write this parameter group, with parameters, to a file handle. Parameters ---------- group_id : int The numerical ID of the group. handle : file handle An open, writable, binary file handle. ''' name = self.name.encode('utf-8') desc = self.desc.encode('utf-8') handle.write(struct.pack('bb', len(name), -group_id)) handle.write(name) handle.write(struct.pack('<h', 3 + len(desc))) handle.write(struct.pack('B', len(desc))) handle.write(desc) for param in self._params.values(): param._data.write(group_id, handle)
class GroupReadonly (data)
-
Wrapper exposing readonly attributes of a
GroupData
entry.Expand source code
class GroupReadonly(object): ''' Wrapper exposing readonly attributes of a `c3d.group.GroupData` entry. ''' def __init__(self, data): self._data = data def __contains__(self, key): return key in self._data._params def __eq__(self, other): return self._data is other._data @property def name(self) -> str: ''' Access group name. ''' return self._data.name @property def desc(self) -> str: '''Access group descriptor. ''' return self._data.desc def items(self): ''' Get iterator for paramater key-entry pairs. ''' return ((k, v.readonly()) for k, v in self._data._params.items()) def values(self): ''' Get iterator for parameter entries. ''' return (v.readonly() for v in self._data._params.values()) def keys(self): ''' Get iterator for parameter entry keys. ''' return self._data._params.keys() def get(self, key, default=None): '''Get a readonly parameter by key. Parameters ---------- key : any Parameter key to look up in this group. default : any, optional Value to return if the key is not found. Defaults to None. Returns ------- param : :class:`ParamReadable` A parameter from the current group. ''' val = self._data._params.get(key, default) if val: return val.readonly() return default def get_int8(self, key): '''Get the value of the given parameter as an 8-bit signed integer.''' return self._data[key.upper()].int8_value def get_uint8(self, key): '''Get the value of the given parameter as an 8-bit unsigned integer.''' return self._data[key.upper()].uint8_value def get_int16(self, key): '''Get the value of the given parameter as a 16-bit signed integer.''' return self._data[key.upper()].int16_value def get_uint16(self, key): '''Get the value of the given parameter as a 16-bit unsigned integer.''' return self._data[key.upper()].uint16_value def get_int32(self, key): '''Get the value of the given parameter as a 32-bit signed integer.''' return self._data[key.upper()].int32_value def get_uint32(self, key): '''Get the value of the given parameter as a 32-bit unsigned integer.''' return self._data[key.upper()].uint32_value def get_float(self, key): '''Get the value of the given parameter as a 32-bit float.''' return self._data[key.upper()].float_value def get_bytes(self, key): '''Get the value of the given parameter as a byte array.''' return self._data[key.upper()].bytes_value def get_string(self, key): '''Get the value of the given parameter as a string.''' return self._data[key.upper()].string_value
Subclasses
Instance variables
var desc : str
-
Access group descriptor.
Expand source code
@property def desc(self) -> str: '''Access group descriptor. ''' return self._data.desc
var name : str
-
Access group name.
Expand source code
@property def name(self) -> str: ''' Access group name. ''' return self._data.name
Methods
def get(self, key, default=None)
-
Get a readonly parameter by key.
Parameters
key
:any
- Parameter key to look up in this group.
default
:any
, optional- Value to return if the key is not found. Defaults to None.
Returns
param
::class:
ParamReadable``- A parameter from the current group.
Expand source code
def get(self, key, default=None): '''Get a readonly parameter by key. Parameters ---------- key : any Parameter key to look up in this group. default : any, optional Value to return if the key is not found. Defaults to None. Returns ------- param : :class:`ParamReadable` A parameter from the current group. ''' val = self._data._params.get(key, default) if val: return val.readonly() return default
def get_bytes(self, key)
-
Get the value of the given parameter as a byte array.
Expand source code
def get_bytes(self, key): '''Get the value of the given parameter as a byte array.''' return self._data[key.upper()].bytes_value
def get_float(self, key)
-
Get the value of the given parameter as a 32-bit float.
Expand source code
def get_float(self, key): '''Get the value of the given parameter as a 32-bit float.''' return self._data[key.upper()].float_value
def get_int16(self, key)
-
Get the value of the given parameter as a 16-bit signed integer.
Expand source code
def get_int16(self, key): '''Get the value of the given parameter as a 16-bit signed integer.''' return self._data[key.upper()].int16_value
def get_int32(self, key)
-
Get the value of the given parameter as a 32-bit signed integer.
Expand source code
def get_int32(self, key): '''Get the value of the given parameter as a 32-bit signed integer.''' return self._data[key.upper()].int32_value
def get_int8(self, key)
-
Get the value of the given parameter as an 8-bit signed integer.
Expand source code
def get_int8(self, key): '''Get the value of the given parameter as an 8-bit signed integer.''' return self._data[key.upper()].int8_value
def get_string(self, key)
-
Get the value of the given parameter as a string.
Expand source code
def get_string(self, key): '''Get the value of the given parameter as a string.''' return self._data[key.upper()].string_value
def get_uint16(self, key)
-
Get the value of the given parameter as a 16-bit unsigned integer.
Expand source code
def get_uint16(self, key): '''Get the value of the given parameter as a 16-bit unsigned integer.''' return self._data[key.upper()].uint16_value
def get_uint32(self, key)
-
Get the value of the given parameter as a 32-bit unsigned integer.
Expand source code
def get_uint32(self, key): '''Get the value of the given parameter as a 32-bit unsigned integer.''' return self._data[key.upper()].uint32_value
def get_uint8(self, key)
-
Get the value of the given parameter as an 8-bit unsigned integer.
Expand source code
def get_uint8(self, key): '''Get the value of the given parameter as an 8-bit unsigned integer.''' return self._data[key.upper()].uint8_value
def items(self)
-
Get iterator for paramater key-entry pairs.
Expand source code
def items(self): ''' Get iterator for paramater key-entry pairs. ''' return ((k, v.readonly()) for k, v in self._data._params.items())
def keys(self)
-
Get iterator for parameter entry keys.
Expand source code
def keys(self): ''' Get iterator for parameter entry keys. ''' return self._data._params.keys()
def values(self)
-
Get iterator for parameter entries.
Expand source code
def values(self): ''' Get iterator for parameter entries. ''' return (v.readonly() for v in self._data._params.values())