Class to wrap numpy structured array
The WrapStruct class is a wrapper around a numpy structured array type.
It implements:
The LabeledWrapStruct subclass adds:
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
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 |
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
endianness : {None, ‘<’,’>’, other endian code} string, optional
check : bool, optional
|
---|
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)
Initialize WrapStruct from binary data block
Parameters: | binaryblock : {None, string} optional
endianness : {None, ‘<’,’>’, other endian code} string, optional
check : bool, optional
|
---|
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)
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: | fieldname : str
|
---|---|
Returns: | label : str
|
Raises: | ValueError :
|
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'
Bases: object
Initialize WrapStruct from binary data block
Parameters: | binaryblock : {None, string} optional
endianness : {None, ‘<’,’>’, other endian code} string, optional
check : bool, optional
|
---|
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)
Initialize WrapStruct from binary data block
Parameters: | binaryblock : {None, string} optional
endianness : {None, ‘<’,’>’, other endian code} string, optional
check : bool, optional
|
---|
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)
return new byteswapped object with given endianness
Guaranteed to make a copy even if endianness is the same as the current endianness.
Parameters: | endianness : None or string, optional
|
---|---|
Returns: | wstr : WrapStruct
|
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
binary block of data as string
Returns: | binaryblock : string
|
---|
Examples
>>> # Make default empty structure
>>> wstr = WrapStruct()
>>> len(wstr.binaryblock)
2
Check structured data with checks
Return copy of structure
>>> wstr = WrapStruct()
>>> wstr['integer'] = 3
>>> wstr2 = wstr.copy()
>>> wstr2 is wstr
False
>>> wstr2['integer']
array(3, dtype=int16)
Return structured array for default structure, with given endianness
Run checks over binary data, return string
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
Return read structure with given or guessed endiancode
Parameters: | fileobj : file-like object
endianness : None or endian code, optional
|
---|---|
Returns: | wstr : WrapStruct object
|
Return value for the key k if present or d otherwise
Guess intended endianness from mapping-like mapping
Parameters: | wstr : mapping-like
|
---|---|
Returns: | endianness : {‘<’, ‘>’}
|
Return items from structured data
Return keys from structured data
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
Traceback (most recent call last):
...
AttributeError: can't set attribute
Return values from structured data
Write structure to fileobj
Write starts at fileobj current file position.
Parameters: | fileobj : file-like object
|
---|---|
Returns: | None : |
Examples
>>> wstr = WrapStruct()
>>> from io import BytesIO
>>> str_io = BytesIO()
>>> wstr.write_to(str_io)
>>> wstr.binaryblock == str_io.getvalue()
True