wrapstruct

Class to wrap numpy structured array

wrapstruct

The WrapStruct class is a wrapper around a numpy structured array type.

It implements:

  • Mappingness from the underlying structured array fields

  • from_fileobj, write_to methods to read and write data to fileobj

  • A mechanism for setting checks and fixes to the data on object creation

  • Endianness guessing, and on-the-fly swapping

The LabeledWrapStruct subclass adds:

Mappingness

You can access and set fields of the contained structarr using standard __getitem__ / __setitem__ syntax:

wrapped[‘field’] = 10

Wrapped structures also implement general mappingness:

wrapped.keys() wrapped.items() wrapped.values()

Properties:

.endianness (read only)
.binaryblock (read only)
.structarr (read only)

Methods:

.as_byteswapped(endianness)
.check_fix()
.__str__
.__eq__
.__ne__
.get_value_label(name)

Class methods:

.diagnose_binaryblock
.as_byteswapped(endianness)
.write_to(fileobj)
.from_fileobj(fileobj)
.default_structarr() - return default structured array
.guessed_endian(structarr) - return guessed endian code from this structarr
Class variables:

template_dtype - native endian version of dtype for contained structarr

Consistency checks

We have a file, and we would like information as to whether there are any problems with the binary data in this file, and whether they are fixable. WrapStruct can hold checks for internal consistency of the contained data:

wrapped = WrapStruct.from_fileobj(open('myfile.bin'), check=False)
dx_result = WrapStruct.diagnose_binaryblock(wrapped.binaryblock)

This will run all known checks, with no fixes, returning a string with diagnostic output. See below for the check=False flag.

In creating a WrapStruct object, we often want to check the consistency of the contained data. The checks can test for problems of various levels of severity. If the problem is severe enough, it should raise an Error. So, with data that is consistent - no error:

wrapped = WrapStruct.from_fileobj(good_fileobj)

whereas:

wrapped = WrapStruct.from_fileobj(bad_fileobj)

would raise some error, with output to logging (see below).

If we want the created object, come what may:

hdr = WrapStruct.from_fileobj(bad_fileobj, check=False)

We set the error level (the level of problem that the check=True versions will accept as OK) from global defaults:

import nibabel as nib
nib.imageglobals.error_level = 30

The same for logging:

nib.imageglobals.logger = logger

LabeledWrapStruct([binaryblock, endianness, …])

A WrapStruct with some fields having value labels for printing etc

WrapStruct([binaryblock, endianness, check])

Initialize WrapStruct from binary data block

WrapStructError

LabeledWrapStruct

class nibabel.wrapstruct.LabeledWrapStruct(binaryblock=None, endianness=None, check=True)

Bases: nibabel.wrapstruct.WrapStruct

A WrapStruct with some fields having value labels for printing etc

Initialize WrapStruct from binary data block

Parameters
binaryblock{None, string} optional

binary block to set into object. By default, None, in which case we insert the default empty block

endianness{None, ‘<’,’>’, other endian code} string, optional

endianness of the binaryblock. If None, guess endianness from the data.

checkbool, optional

Whether to check content of binary data in initialization. Default is True.

Examples

>>> wstr1 = WrapStruct() # a default structure
>>> wstr1.endianness == native_code
True
>>> wstr1['integer']
array(0, dtype=int16)
>>> wstr1['integer'] = 1
>>> wstr1['integer']
array(1, dtype=int16)
__init__(binaryblock=None, endianness=None, check=True)

Initialize WrapStruct from binary data block

Parameters
binaryblock{None, string} optional

binary block to set into object. By default, None, in which case we insert the default empty block

endianness{None, ‘<’,’>’, other endian code} string, optional

endianness of the binaryblock. If None, guess endianness from the data.

checkbool, optional

Whether to check content of binary data in initialization. Default is True.

Examples

>>> wstr1 = WrapStruct() # a default structure
>>> wstr1.endianness == native_code
True
>>> wstr1['integer']
array(0, dtype=int16)
>>> wstr1['integer'] = 1
>>> wstr1['integer']
array(1, dtype=int16)
get_value_label(fieldname)

Returns label for coded field

A coded field is an int field containing codes that stand for discrete values that also have string labels.

Parameters
fieldnamestr

name of header field to get label for

Returns
labelstr

label for code value in header field fieldname

Raises
ValueError

if field is not coded.

Examples

>>> from nibabel.volumeutils import Recoder
>>> recoder = Recoder(((1, 'one'), (2, 'two')), ('code', 'label'))
>>> class C(LabeledWrapStruct):
...     template_dtype = np.dtype([('datatype', 'i2')])
...     _field_recoders = dict(datatype = recoder)
>>> hdr  = C()
>>> hdr.get_value_label('datatype')
'<unknown code 0>'
>>> hdr['datatype'] = 2
>>> hdr.get_value_label('datatype')
'two'

WrapStruct

class nibabel.wrapstruct.WrapStruct(binaryblock=None, endianness=None, check=True)

Bases: object

Initialize WrapStruct from binary data block

Parameters
binaryblock{None, string} optional

binary block to set into object. By default, None, in which case we insert the default empty block

endianness{None, ‘<’,’>’, other endian code} string, optional

endianness of the binaryblock. If None, guess endianness from the data.

checkbool, optional

Whether to check content of binary data in initialization. Default is True.

Examples

>>> wstr1 = WrapStruct() # a default structure
>>> wstr1.endianness == native_code
True
>>> wstr1['integer']
array(0, dtype=int16)
>>> wstr1['integer'] = 1
>>> wstr1['integer']
array(1, dtype=int16)
__init__(binaryblock=None, endianness=None, check=True)

Initialize WrapStruct from binary data block

Parameters
binaryblock{None, string} optional

binary block to set into object. By default, None, in which case we insert the default empty block

endianness{None, ‘<’,’>’, other endian code} string, optional

endianness of the binaryblock. If None, guess endianness from the data.

checkbool, optional

Whether to check content of binary data in initialization. Default is True.

Examples

>>> wstr1 = WrapStruct() # a default structure
>>> wstr1.endianness == native_code
True
>>> wstr1['integer']
array(0, dtype=int16)
>>> wstr1['integer'] = 1
>>> wstr1['integer']
array(1, dtype=int16)
as_byteswapped(endianness=None)

return new byteswapped object with given endianness

Guaranteed to make a copy even if endianness is the same as the current endianness.

Parameters
endiannessNone or string, optional

endian code to which to swap. None means swap from current endianness, and is the default

Returns
wstrWrapStruct

WrapStruct object with given endianness

Examples

>>> wstr = WrapStruct()
>>> wstr.endianness == native_code
True
>>> bs_wstr = wstr.as_byteswapped()
>>> bs_wstr.endianness == swapped_code
True
>>> bs_wstr = wstr.as_byteswapped(swapped_code)
>>> bs_wstr.endianness == swapped_code
True
>>> bs_wstr is wstr
False
>>> bs_wstr == wstr
True

If you write to the resulting byteswapped data, it does not change the original.

>>> bs_wstr['integer'] = 3
>>> bs_wstr == wstr
False

If you swap to the same endianness, it returns a copy

>>> nbs_wstr = wstr.as_byteswapped(native_code)
>>> nbs_wstr.endianness == native_code
True
>>> nbs_wstr is wstr
False
binaryblock

binary block of data as string

Returns
binaryblockstring

string giving binary data block

Examples

>>> # Make default empty structure
>>> wstr = WrapStruct()
>>> len(wstr.binaryblock)
2
check_fix(logger=None, error_level=None)

Check structured data with checks

Parameters
loggerNone or logging.Logger
error_levelNone or int

Level of error severity at which to raise error. Any error of severity >= error_level will cause an exception.

copy()

Return copy of structure

>>> wstr = WrapStruct()
>>> wstr['integer'] = 3
>>> wstr2 = wstr.copy()
>>> wstr2 is wstr
False
>>> wstr2['integer']
array(3, dtype=int16)
classmethod default_structarr(endianness=None)

Return structured array for default structure with given endianness

classmethod diagnose_binaryblock(binaryblock, endianness=None)

Run checks over binary data, return string

endianness

endian code of binary data

The endianness code gives the current byte order interpretation of the binary data.

Notes

Endianness gives endian interpretation of binary data. It is read only because the only common use case is to set the endianness on initialization, or occasionally byteswapping the data - but this is done via the as_byteswapped method

Examples

>>> wstr = WrapStruct()
>>> code = wstr.endianness
>>> code == native_code
True
classmethod from_fileobj(fileobj, endianness=None, check=True)

Return read structure with given or guessed endiancode

Parameters
fileobjfile-like object

Needs to implement read method

endiannessNone or endian code, optional

Code specifying endianness of read data

Returns
wstrWrapStruct object

WrapStruct object initialized from data in fileobj

get(k, d=None)

Return value for the key k if present or d otherwise

classmethod guessed_endian(mapping)

Guess intended endianness from mapping-like mapping

Parameters
wstrmapping-like

Something implementing a mapping. We will guess the endianness from looking at the field values

Returns
endianness{‘<’, ‘>’}

Guessed endianness of binary data in wstr

items()

Return items from structured data

keys()

Return keys from structured data

structarr

Structured data, with data fields

Examples

>>> wstr1 = WrapStruct() # with default data
>>> an_int = wstr1.structarr['integer']
>>> wstr1.structarr = None
Traceback (most recent call last):
   ...
AttributeError: can't set attribute
template_dtype = dtype([('integer', '<i2')])
values()

Return values from structured data

write_to(fileobj)

Write structure to fileobj

Write starts at fileobj current file position.

Parameters
fileobjfile-like object

Should implement write method

Returns
None

Examples

>>> wstr = WrapStruct()
>>> from io import BytesIO
>>> str_io = BytesIO()
>>> wstr.write_to(str_io)
>>> wstr.binaryblock == str_io.getvalue()
True

WrapStructError

class nibabel.wrapstruct.WrapStructError

Bases: Exception

__init__($self, /, *args, **kwargs)

Initialize self. See help(type(self)) for accurate signature.