From bdfe5f019373d5e292cdfa90062444ad28db104a Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Fri, 20 Jul 2012 14:50:09 -0400 Subject: [PATCH] Rework igor.struct to support dynamic structures. Between binarywave and record.variables, there was a good deal of parsing that was conditional on previously parsed data. Rather than continue writing spaghetti code to handle each specific case, I've taken a stab at a general framework for updating structures during parsing (DynamicStructure and DynamicField). The docstrings should explain how they work. The implementation still has a few holes, but it works on each of the files in my test suite. --- igor/binarywave.py | 605 +++++++---- igor/packed.py | 57 +- igor/record/variables.py | 365 ++++--- igor/record/wave.py | 3 +- igor/struct.py | 441 +++++++- test/test.py | 2040 +++++++++++++++++++------------------- 6 files changed, 2083 insertions(+), 1428 deletions(-) diff --git a/igor/binarywave.py b/igor/binarywave.py index e7f1282..ee70be2 100644 --- a/igor/binarywave.py +++ b/igor/binarywave.py @@ -26,14 +26,19 @@ # share. We hope IGOR Technical Notes will provide you with lots of # valuable information while you are developing IGOR applications. +from __future__ import absolute_import import array as _array +import struct as _struct import sys as _sys import types as _types import numpy as _numpy +from . import LOG as _LOG from .struct import Structure as _Structure +from .struct import DynamicStructure as _DynamicStructure from .struct import Field as _Field +from .struct import DynamicField as _DynamicField from .util import assert_null as _assert_null from .util import byte_order as _byte_order from .util import need_to_reorder_bytes as _need_to_reorder_bytes @@ -55,6 +60,40 @@ complexUInt16 = _numpy.dtype( complexUInt32 = _numpy.dtype( [('real', _numpy.uint32), ('imag', _numpy.uint32)]) + +class StaticStringField (_DynamicField): + _null_terminated = False + _array_size_field = None + def post_unpack(self, parents, data): + wave_structure = parents[-1] + wave_data = self._get_structure_data(parents, data, wave_structure) + d = self._normalize_string(wave_data[self.name]) + wave_data[self.name] = d + + def _normalize_string(self, d): + if hasattr(d, 'tostring'): + d = d.tostring() + else: + d = ''.join(d) + if self._array_size_field: + start = 0 + strings = [] + for count in self.counts: + end = start + count + if end > start: + strings.append(d[start:end]) + if self._null_terminated: + strings[-1] = strings[-1].split('\x00', 1)[0] + start = end + elif self._null_terminated: + d = d.split('\x00', 1)[0] + return d + + +class NullStaticStringField (StaticStringField): + _null_terminated = True + + # Begin IGOR constants and typedefs from IgorBin.h # From IgorMath.h @@ -88,45 +127,35 @@ TYPE_TABLE = { # (key: integer flag, value: numpy dtype) MAXDIMS = 4 # From binary.h -BinHeaderCommon = _Structure( # WTK: this one is mine. - name='BinHeaderCommon', - fields=[ - _Field('h', 'version', help='Version number for backwards compatibility.'), - ]) - -BinHeader1 = _Structure( +BinHeader1 = _Structure( # `version` field pulled out into Wave name='BinHeader1', fields=[ - _Field('h', 'version', help='Version number for backwards compatibility.'), _Field('l', 'wfmSize', help='The size of the WaveHeader2 data structure plus the wave data plus 16 bytes of padding.'), _Field('h', 'checksum', help='Checksum over this header and the wave header.'), ]) -BinHeader2 = _Structure( +BinHeader2 = _Structure( # `version` field pulled out into Wave name='BinHeader2', fields=[ - _Field('h', 'version', help='Version number for backwards compatibility.'), _Field('l', 'wfmSize', help='The size of the WaveHeader2 data structure plus the wave data plus 16 bytes of padding.'), _Field('l', 'noteSize', help='The size of the note text.'), _Field('l', 'pictSize', default=0, help='Reserved. Write zero. Ignore on read.'), _Field('h', 'checksum', help='Checksum over this header and the wave header.'), ]) -BinHeader3 = _Structure( +BinHeader3 = _Structure( # `version` field pulled out into Wave name='BinHeader3', fields=[ - _Field('h', 'version', help='Version number for backwards compatibility.'), - _Field('h', 'wfmSize', help='The size of the WaveHeader2 data structure plus the wave data plus 16 bytes of padding.'), + _Field('l', 'wfmSize', help='The size of the WaveHeader2 data structure plus the wave data plus 16 bytes of padding.'), _Field('l', 'noteSize', help='The size of the note text.'), _Field('l', 'formulaSize', help='The size of the dependency formula, if any.'), _Field('l', 'pictSize', default=0, help='Reserved. Write zero. Ignore on read.'), _Field('h', 'checksum', help='Checksum over this header and the wave header.'), ]) -BinHeader5 = _Structure( +BinHeader5 = _Structure( # `version` field pulled out into Wave name='BinHeader5', fields=[ - _Field('h', 'version', help='Version number for backwards compatibility.'), _Field('h', 'checksum', help='Checksum over this header and the wave header.'), _Field('l', 'wfmSize', help='The size of the WaveHeader5 data structure plus the wave data.'), _Field('l', 'formulaSize', help='The size of the dependency formula, if any.'), @@ -149,12 +178,13 @@ MAX_UNIT_CHARS = 3 # Header to an array of waveform data. -WaveHeader2 = _Structure( +# `wData` field pulled out into DynamicWaveDataField1 +WaveHeader2 = _DynamicStructure( name='WaveHeader2', fields=[ _Field('h', 'type', help='See types (e.g. NT_FP64) above. Zero for text waves.'), _Field('P', 'next', default=0, help='Used in memory only. Write zero. Ignore on read.'), - _Field('c', 'bname', help='Name of wave plus trailing null.', count=MAX_WAVE_NAME2+2), + NullStaticStringField('c', 'bname', help='Name of wave plus trailing null.', count=MAX_WAVE_NAME2+2), _Field('h', 'whVersion', default=0, help='Write 0. Ignore on read.'), _Field('h', 'srcFldr', default=0, help='Used in memory only. Write zero. Ignore on read.'), _Field('P', 'fileName', default=0, help='Used in memory only. Write zero. Ignore on read.'), @@ -177,10 +207,12 @@ WaveHeader2 = _Structure( _Field('c', 'wUnused', default=0, help='Reserved. Write zero. Ignore on read.', count=2), _Field('L', 'modDate', help='DateTime of last modification.'), _Field('P', 'waveNoteH', help='Used in memory only. Write zero. Ignore on read.'), - _Field('f', 'wData', help='The start of the array of waveform data.', count=4), ]) -WaveHeader5 = _Structure( +# `sIndices` pointer unset (use Wave5_data['sIndices'] instead). This +# field is filled in by DynamicStringIndicesDataField. +# `wData` field pulled out into DynamicWaveDataField5 +WaveHeader5 = _DynamicStructure( name='WaveHeader5', fields=[ _Field('P', 'next', help='link to next wave in linked list.'), @@ -191,7 +223,7 @@ WaveHeader5 = _Structure( _Field('h', 'dLock', default=0, help='Reserved. Write zero. Ignore on read.'), _Field('c', 'whpad1', default=0, help='Reserved. Write zero. Ignore on read.', count=6), _Field('h', 'whVersion', default=1, help='Write 1. Ignore on read.'), - _Field('c', 'bname', help='Name of wave plus trailing null.', count=MAX_WAVE_NAME5+1), + NullStaticStringField('c', 'bname', help='Name of wave plus trailing null.', count=MAX_WAVE_NAME5+1), _Field('l', 'whpad2', default=0, help='Reserved. Write zero. Ignore on read.'), _Field('P', 'dFolder', default=0, help='Used in memory only. Write zero. Ignore on read.'), # Dimensioning info. [0] == rows, [1] == cols etc @@ -222,197 +254,386 @@ WaveHeader5 = _Structure( _Field('h', 'srcFldr', default=0, help='Used in memory only. Write zero. Ignore on read.'), _Field('P', 'fileName', default=0, help='Used in memory only. Write zero. Ignore on read.'), _Field('P', 'sIndices', default=0, help='Used in memory only. Write zero. Ignore on read.'), - _Field('f', 'wData', help='The start of the array of data. Must be 64 bit aligned.', count=1), ]) -# End IGOR constants and typedefs from IgorBin.h -def _version_structs(version, byte_order): - if version == 1: - bin = BinHeader1 - wave = WaveHeader2 - elif version == 2: - bin = BinHeader2 - wave = WaveHeader2 - elif version == 3: - bin = BinHeader3 - wave = WaveHeader2 - elif version == 5: - bin = BinHeader5 - wave = WaveHeader5 - else: - raise ValueError( - ('This does not appear to be a valid Igor binary wave file. ' - 'The version field = {}.\n').format(version)) - checkSumSize = bin.size + wave.size - if version == 5: - checkSumSize -= 4 # Version 5 checksum does not include the wData field. - bin.set_byte_order(byte_order) - wave.set_byte_order(byte_order) - return (bin, wave, checkSumSize) - -# Translated from ReadWave() -def load(filename, strict=True): - if hasattr(filename, 'read'): - f = filename # filename is actually a stream object - else: - f = open(filename, 'rb') - try: - BinHeaderCommon.set_byte_order('=') - b = buffer(f.read(BinHeaderCommon.size)) - version = BinHeaderCommon.unpack_from(b)['version'] - needToReorderBytes = _need_to_reorder_bytes(version) - byteOrder = _byte_order(needToReorderBytes) - - if needToReorderBytes: - BinHeaderCommon.set_byte_order(byteOrder) - version = BinHeaderCommon.unpack_from(b)['version'] - bin_struct,wave_struct,checkSumSize = _version_structs( - version, byteOrder) - - b = buffer(b + f.read(bin_struct.size + wave_struct.size - BinHeaderCommon.size)) - c = _checksum(b, byteOrder, 0, checkSumSize) - if c != 0: - raise ValueError( - ('This does not appear to be a valid Igor binary wave file. ' - 'Error in checksum: should be 0, is {}.').format(c)) - bin_info = bin_struct.unpack_from(b) - wave_info = wave_struct.unpack_from(b, offset=bin_struct.size) - if version in [1,2,3]: - tail = 16 # 16 = size of wData field in WaveHeader2 structure - waveDataSize = bin_info['wfmSize'] - wave_struct.size - # = bin_info['wfmSize']-16 - (wave_struct.size - tail) - else: - assert version == 5, version - tail = 4 # 4 = size of wData field in WaveHeader5 structure - waveDataSize = bin_info['wfmSize'] - (wave_struct.size - tail) +class DynamicWaveDataField1 (_DynamicField): + def pre_pack(self, parents, data): + raise NotImplementedError() + + def pre_unpack(self, parents, data): + full_structure = parents[0] + wave_structure = parents[-1] + wave_header_structure = wave_structure.fields[1].format + wave_data = self._get_structure_data(parents, data, wave_structure) + version = data['version'] + bin_header = wave_data['bin_header'] + wave_header = wave_data['wave_header'] + + self.count = wave_header['npnts'] + self.data_size = self._get_size(bin_header, wave_header_structure.size) + + type_ = TYPE_TABLE.get(wave_header['type'], None) + if type_: + self.shape = self._get_shape(bin_header, wave_header) + else: # text wave + type_ = _numpy.dtype('S1') + self.shape = (self.data_size,) # dtype() wrapping to avoid numpy.generic and # getset_descriptor issues with the builtin numpy types # (e.g. int32). It has no effect on our local complex # integers. - if version == 5: - shape = [n for n in wave_info['nDim'] if n > 0] or (0,) + self.dtype = _numpy.dtype(type_).newbyteorder( + wave_structure.byte_order) + if (version == 3 and + self.count > 0 and + bin_header['formulaSize'] > 0 and + self.data_size == 0): + """From TN003: + + Igor Pro 2.00 included support for dependency formulae. If + a wave was governed by a dependency formula then the + actual wave data was not written to disk for that wave, + because on loading the wave Igor could recalculate the + data. However,this prevented the wave from being loaded + into an experiment other than the original + experiment. Consequently, in a version of Igor Pro 3.0x, + we changed it so that the wave data was written even if + the wave was governed by a dependency formula. When + reading a binary wave file, you can detect that the wave + file does not contain the wave data by examining the + wfmSize, formulaSize and npnts fields. If npnts is greater + than zero and formulaSize is greater than zero and + the waveDataSize as calculated above is zero, then this is + a file governed by a dependency formula that was written + without the actual wave data. + """ + self.shape = (0,) + elif TYPE_TABLE.get(wave_header['type'], None) is not None: + assert self.data_size == self.count * self.dtype.itemsize, ( + self.data_size, self.count, self.dtype.itemsize, self.dtype) else: - shape = (wave_info['npnts'],) - t = _numpy.dtype(_numpy.int8) # setup a safe default - if wave_info['type'] == 0: # text wave - shape = (waveDataSize,) - elif wave_info['type'] in TYPE_TABLE or wave_info['npnts']: - t = _numpy.dtype(TYPE_TABLE[wave_info['type']]) - assert waveDataSize == wave_info['npnts'] * t.itemsize, ( - '{}, {}, {}, {}'.format( - waveDataSize, wave_info['npnts'], t.itemsize, t)) + assert self.data_size >= 0, ( + bin_header['wfmSize'], wave_header_structure.size) + + def _get_size(self, bin_header, wave_header_size): + return bin_header['wfmSize'] - wave_header_size - 16 + + def _get_shape(self, bin_header, wave_header): + return (self.count,) + + def unpack(self, stream): + data_b = stream.read(self.data_size) + try: + data = _numpy.ndarray( + shape=self.shape, + dtype=self.dtype, + buffer=data_b, + order='F', + ) + except: + _LOG.error( + 'could not reshape data from {} to {}'.format( + self.shape, data_b)) + raise + return data + + +class DynamicWaveDataField5 (DynamicWaveDataField1): + "Adds support for multidimensional data." + def _get_size(self, bin_header, wave_header_size): + return bin_header['wfmSize'] - wave_header_size + + def _get_shape(self, bin_header, wave_header): + return [n for n in wave_header['nDim'] if n > 0] or (0,) + + +# End IGOR constants and typedefs from IgorBin.h + + +class DynamicStringField (StaticStringField): + _size_field = None + + def pre_unpack(self, parents, data): + size = self._get_size_data(parents, data) + if self._array_size_field: + self.counts = size + self.count = sum(self.counts) else: - pass # formula waves - if wave_info['npnts'] == 0: - data_b = buffer('') + self.count = size + self.setup() + + def _get_size_data(self, parents, data): + wave_structure = parents[-1] + wave_data = self._get_structure_data(parents, data, wave_structure) + bin_header = wave_data['bin_header'] + return bin_header[self._size_field] + + +class DynamicWaveNoteField (DynamicStringField): + _size_field = 'noteSize' + + +class DynamicDependencyFormulaField (DynamicStringField): + """Optional wave dependency formula + + Excerpted from TN003: + + A wave has a dependency formula if it has been bound by a + statement such as "wave0 := sin(x)". In this example, the + dependency formula is "sin(x)". The formula is stored with + no trailing null byte. + """ + _size_field = 'formulaSize' + # Except when it is stored with a trailing null byte :p. See, for + # example, test/data/mac-version3Dependent.ibw. + _null_terminated = True + + +class DynamicDataUnitsField (DynamicStringField): + """Optional extended data units data + + Excerpted from TN003: + + dataUnits - Present in versions 1, 2, 3, 5. The dataUnits field + stores the units for the data represented by the wave. It is a C + string terminated with a null character. This field supports + units of 0 to 3 bytes. In version 1, 2 and 3 files, longer units + can not be represented. In version 5 files, longer units can be + stored using the optional extended data units section of the + file. + """ + _size_field = 'dataEUnitsSize' + + +class DynamicDimensionUnitsField (DynamicStringField): + """Optional extended dimension units data + + Excerpted from TN003: + + xUnits - Present in versions 1, 2, 3. The xUnits field stores the + X units for a wave. It is a C string terminated with a null + character. This field supports units of 0 to 3 bytes. In + version 1, 2 and 3 files, longer units can not be represented. + + dimUnits - Present in version 5 only. This field is an array of 4 + strings, one for each possible wave dimension. Each string + supports units of 0 to 3 bytes. Longer units can be stored using + the optional extended dimension units section of the file. + """ + _size_field = 'dimEUnitsSize' + _array_size_field = True + + +class DynamicLabelsField (DynamicStringField): + """Optional dimension label data + + From TN003: + + If the wave has dimension labels for dimension d then the + dimLabelsSize[d] field of the BinHeader5 structure will be + non-zero. + + A wave will have dimension labels if a SetDimLabel command has + been executed on it. + + A 3 point 1D wave has 4 dimension labels. The first dimension + label is the label for the dimension as a whole. The next three + dimension labels are the labels for rows 0, 1, and 2. When Igor + writes dimension labels to disk, it writes each dimension label as + a C string (null-terminated) in a field of 32 bytes. + """ + _size_field = 'dimLabelsSize' + _array_size_field = True + + def post_unpack(self, parents, data): + wave_structure = parents[-1] + wave_data = self._get_structure_data(parents, data, wave_structure) + bin_header = wave_data['bin_header'] + d = ''.join(wave_data[self.name]) + dim_labels = [] + start = 0 + for size in bin_header[self._size_field]: + end = start + size + if end > start: + dim_data = d[start:end] + # split null-delimited strings + labels = dim_data.split(chr(0)) + start = end + else: + labels = [] + dim_labels.append(labels) + wave_data[self.name] = dim_labels + + +class DynamicStringIndicesDataField (_DynamicField): + """String indices used for text waves only + """ + def pre_pack(self, parents, data): + raise NotImplementedError() + + def pre_unpack(self, parents, data): + wave_structure = parents[-1] + wave_data = self._get_structure_data(parents, data, wave_structure) + bin_header = wave_data['bin_header'] + wave_header = wave_data['wave_header'] + self.string_indices_size = bin_header['sIndicesSize'] + self.count = self.string_indices_size / 4 + if self.count: # make sure we're in a text wave + assert TYPE_TABLE[wave_header['type']] is None, wave_header + self.setup() + + def post_unpack(self, parents, data): + if not self.count: + return + wave_structure = parents[-1] + wave_data = self._get_structure_data(parents, data, wave_structure) + wave_header = wave_data['wave_header'] + wdata = wave_data['wData'] + strings = [] + start = 0 + for i,offset in enumerate(wave_data['sIndices']): + if offset > start: + chars = wdata[start:offset] + strings.append(''.join(chars)) + start = offset + elif offset == start: + strings.append('') + else: + raise ValueError((offset, wave_data['sIndices'])) + wdata = _numpy.array(strings) + shape = [n for n in wave_header['nDim'] if n > 0] or (0,) + try: + wdata = wdata.reshape(shape) + except ValueError: + _LOG.error( + 'could not reshape strings from {} to {}'.format( + shape, wdata.shape)) + raise + wave_data['wData'] = wdata + + +class DynamicVersionField (_DynamicField): + def pre_pack(self, parents, byte_order): + raise NotImplementedError() + + def post_unpack(self, parents, data): + wave_structure = parents[-1] + wave_data = self._get_structure_data(parents, data, wave_structure) + version = wave_data['version'] + if wave_structure.byte_order in '@=': + need_to_reorder_bytes = _need_to_reorder_bytes(version) + wave_structure.byte_order = _byte_order(need_to_reorder_bytes) + _LOG.debug( + 'get byte order from version: {} (reorder? {})'.format( + wave_structure.byte_order, need_to_reorder_bytes)) else: - tail_data = _array.array('f', b[-tail:]) - data_b = buffer(buffer(tail_data) + f.read(waveDataSize-tail)) - data = _numpy.ndarray( - shape=shape, - dtype=t.newbyteorder(byteOrder), - buffer=data_b, - order='F', - ) + need_to_reorder_bytes = False + old_format = wave_structure.fields[-1].format if version == 1: - pass # No post-data information + wave_structure.fields[-1].format = Wave1 elif version == 2: - # Post-data info: - # * 16 bytes of padding - # * Optional wave note data - pad_b = buffer(f.read(16)) # skip the padding - _assert_null(pad_b, strict=strict) - bin_info['note'] = str(f.read(bin_info['noteSize'])).strip() + wave_structure.fields[-1].format = Wave2 elif version == 3: - # Post-data info: - # * 16 bytes of padding - # * Optional wave note data - # * Optional wave dependency formula - """Excerpted from TN003: - - A wave has a dependency formula if it has been bound by a - statement such as "wave0 := sin(x)". In this example, the - dependency formula is "sin(x)". The formula is stored with - no trailing null byte. - """ - pad_b = buffer(f.read(16)) # skip the padding - _assert_null(pad_b, strict=strict) - bin_info['note'] = str(f.read(bin_info['noteSize'])).strip() - bin_info['formula'] = str(f.read(bin_info['formulaSize'])).strip() + wave_structure.fields[-1].format = Wave3 elif version == 5: - # Post-data info: - # * Optional wave dependency formula - # * Optional wave note data - # * Optional extended data units data - # * Optional extended dimension units data - # * Optional dimension label data - # * String indices used for text waves only - """Excerpted from TN003: - - dataUnits - Present in versions 1, 2, 3, 5. The dataUnits - field stores the units for the data represented by the - wave. It is a C string terminated with a null - character. This field supports units of 0 to 3 bytes. In - version 1, 2 and 3 files, longer units can not be - represented. In version 5 files, longer units can be - stored using the optional extended data units section of - the file. - - xUnits - Present in versions 1, 2, 3. The xUnits field - stores the X units for a wave. It is a C string - terminated with a null character. This field supports - units of 0 to 3 bytes. In version 1, 2 and 3 files, - longer units can not be represented. - - dimUnits - Present in version 5 only. This field is an - array of 4 strings, one for each possible wave - dimension. Each string supports units of 0 to 3 - bytes. Longer units can be stored using the optional - extended dimension units section of the file. - """ - bin_info['formula'] = str(f.read(bin_info['formulaSize'])).strip() - bin_info['note'] = str(f.read(bin_info['noteSize'])).strip() - bin_info['dataEUnits'] = str(f.read(bin_info['dataEUnitsSize'])).strip() - bin_info['dimEUnits'] = [ - str(f.read(size)).strip() for size in bin_info['dimEUnitsSize']] - bin_info['dimLabels'] = [] - for size in bin_info['dimLabelsSize']: - labels = str(f.read(size)).split(chr(0)) # split null-delimited strings - bin_info['dimLabels'].append([L for L in labels if len(L) > 0]) - if wave_info['type'] == 0: # text wave - sIndices_data = f.read(bin_info['sIndicesSize']) - sIndices_count = bin_info['sIndicesSize']/4 - bin_info['sIndices'] = _numpy.ndarray( - shape=(sIndices_count,), - dtype=_numpy.dtype( - _numpy.uint32()).newbyteorder(byteOrder), - buffer=sIndices_data, - order='F', - ) - - if wave_info['type'] == 0: # text wave - # use sIndices to split data into strings - strings = [] - start = 0 - for i,offset in enumerate(bin_info['sIndices']): - if offset > start: - string = data[start:offset] - strings.append(''.join(chr(x) for x in string)) - start = offset - elif offset == start: - strings.append('') - else: - raise ValueError((offset, bin_info['sIndices'])) - data = _numpy.array(strings) - shape = [n for n in wave_info['nDim'] if n > 0] or (0,) - data.reshape(shape) + wave_structure.fields[-1].format = Wave5 + elif not need_to_reorder_bytes: + raise ValueError( + 'invalid binary wave version: {}'.format(version)) + + if wave_structure.fields[-1].format != old_format: + _LOG.debug('change wave headers from {} to {}'.format( + old_format, wave_structure.fields[-1].format)) + wave_structure.setup() + elif need_to_reorder_bytes: + wave_structure.setup() + + # we might need to unpack again with the new byte order + return need_to_reorder_bytes + + +class DynamicWaveField (_DynamicField): + def post_unpack(self, parents, data): + return + raise NotImplementedError() # TODO + checksum_size = bin.size + wave.size + wave_structure = parents[-1] + if version == 5: + # Version 5 checksum does not include the wData field. + checksum_size -= 4 + c = _checksum(b, parents[-1].byte_order, 0, checksum_size) + if c != 0: + raise ValueError( + ('This does not appear to be a valid Igor binary wave file. ' + 'Error in checksum: should be 0, is {}.').format(c)) + +Wave1 = _DynamicStructure( + name='Wave1', + fields=[ + _Field(BinHeader1, 'bin_header', help='Binary wave header'), + _Field(WaveHeader2, 'wave_header', help='Wave header'), + DynamicWaveDataField1('f', 'wData', help='The start of the array of waveform data.', count=0), + ]) + +Wave2 = _DynamicStructure( + name='Wave2', + fields=[ + _Field(BinHeader2, 'bin_header', help='Binary wave header'), + _Field(WaveHeader2, 'wave_header', help='Wave header'), + DynamicWaveDataField1('f', 'wData', help='The start of the array of waveform data.', count=0), + _Field('x', 'padding', help='16 bytes of padding in versions 2 and 3.', count=16), + DynamicWaveNoteField('c', 'note', help='Optional wave note data', count=0), + ]) + +Wave3 = _DynamicStructure( + name='Wave3', + fields=[ + _Field(BinHeader3, 'bin_header', help='Binary wave header'), + _Field(WaveHeader2, 'wave_header', help='Wave header'), + DynamicWaveDataField1('f', 'wData', help='The start of the array of waveform data.', count=0), + _Field('x', 'padding', help='16 bytes of padding in versions 2 and 3.', count=16), + DynamicWaveNoteField('c', 'note', help='Optional wave note data', count=0), + DynamicDependencyFormulaField('c', 'formula', help='Optional wave dependency formula', count=0), + ]) + +Wave5 = _DynamicStructure( + name='Wave5', + fields=[ + _Field(BinHeader5, 'bin_header', help='Binary wave header'), + _Field(WaveHeader5, 'wave_header', help='Wave header'), + DynamicWaveDataField5('f', 'wData', help='The start of the array of waveform data.', count=0), + DynamicDependencyFormulaField('c', 'formula', help='Optional wave dependency formula.', count=0), + DynamicWaveNoteField('c', 'note', help='Optional wave note data.', count=0), + DynamicDataUnitsField('c', 'data_units', help='Optional extended data units data.', count=0), + DynamicDimensionUnitsField('c', 'dimension_units', help='Optional dimension label data', count=0), + DynamicLabelsField('c', 'labels', help="Optional dimension label data", count=0), + DynamicStringIndicesDataField('P', 'sIndices', help='Dynamic string indices for text waves.', count=0), + ]) + +Wave = _DynamicStructure( + name='Wave', + fields=[ + DynamicVersionField('h', 'version', help='Version number for backwards compatibility.'), + DynamicWaveField(Wave1, 'wave', help='The rest of the wave data.'), + ]) + + +def load(filename): + if hasattr(filename, 'read'): + f = filename # filename is actually a stream object + else: + f = open(filename, 'rb') + try: + Wave.byte_order = '=' + Wave.setup() + data = Wave.unpack_stream(f) finally: if not hasattr(filename, 'read'): f.close() - return data, bin_info, wave_info + return data def save(filename): diff --git a/igor/packed.py b/igor/packed.py index baad25e..564725a 100644 --- a/igor/packed.py +++ b/igor/packed.py @@ -2,6 +2,7 @@ "Read IGOR Packed Experiment files files into records." +from . import LOG as _LOG from .struct import Structure as _Structure from .struct import Field as _Field from .util import byte_order as _byte_order @@ -39,6 +40,7 @@ SUPERCEDED_MASK = 0x8000 # Bit is set if the record is superceded by def load(filename, strict=True, ignore_unknown=True): + _LOG.debug('loading a packed experiment file from {}'.format(filename)) records = [] if hasattr(filename, 'read'): f = filename # filename is actually a stream object @@ -48,26 +50,38 @@ def load(filename, strict=True, ignore_unknown=True): initial_byte_order = '=' try: while True: + PackedFileRecordHeader.byte_order = initial_byte_order + PackedFileRecordHeader.setup() b = buffer(f.read(PackedFileRecordHeader.size)) if not b: break - PackedFileRecordHeader.set_byte_order(initial_byte_order) + _LOG.debug('reading a new packed experiment file record') header = PackedFileRecordHeader.unpack_from(b) if header['version'] and not byte_order: need_to_reorder = _need_to_reorder_bytes(header['version']) byte_order = initial_byte_order = _byte_order(need_to_reorder) + _LOG.debug( + 'get byte order from version: {} (reorder? {})'.format( + byte_order, need_to_reorder)) if need_to_reorder: - PackedFileRecordHeader.set_byte_order(byte_order) + PackedFileRecordHeader.byte_order = byte_order + PackedFileRecordHeader.setup() header = PackedFileRecordHeader.unpack_from(b) + _LOG.debug( + 'reordered version: {}'.format(header['version'])) data = buffer(f.read(header['numDataBytes'])) record_type = _RECORD_TYPE.get( header['recordType'] & PACKEDRECTYPE_MASK, _UnknownRecord) + _LOG.debug('the new record has type {} ({}).'.format( + record_type, header['recordType'])) if record_type in [_UnknownRecord, _UnusedRecord ] and not ignore_unknown: raise KeyError('unkown record type {}'.format( header['recordType'])) records.append(record_type(header, data, byte_order=byte_order)) finally: + _LOG.debug('finished loading {} records from {}'.format( + len(records), filename)) if not hasattr(filename, 'read'): f.close() @@ -122,15 +136,19 @@ def _build_filesystem(records): dir_stack.pop() elif isinstance(record, (_VariablesRecord, _WaveRecord)): if isinstance(record, _VariablesRecord): - _add_variables(dir_stack, cwd, record) - # start with an invalid character to avoid collisions - # with folder names - #filename = ':variables' - #_check_filename(dir_stack, filename) - #cwd[filename] = record + sys_vars = record.variables['variables']['sysVars'].keys() + for filename,value in record.namespace.items(): + if len(dir_stack) > 1 and filename in sys_vars: + # From PTN003: + """When reading a packed file, any system + variables encountered while the current data + folder is not the root should be ignored. + """ + continue + _check_filename(dir_stack, filename) + cwd[filename] = value else: # WaveRecord - filename = ''.join(c for c in record.wave_info['bname'] - ).split('\x00', 1)[0] + filename = record.wave['wave']['wave_header']['bname'] _check_filename(dir_stack, filename) cwd[filename] = record return filesystem @@ -140,22 +158,3 @@ def _check_filename(dir_stack, filename): if filename in cwd: raise ValueError('collision on name {} in {}'.format( filename, ':'.join(d for d,cwd in dir_stack))) - -def _add_variables(dir_stack, cwd, record): - if len(dir_stack) == 1: - # From PTN003: - """When reading a packed file, any system variables - encountered while the current data folder is not the root - should be ignored. - """ - for i,value in enumerate(record.variables['sysVars']): - name = 'K{}'.format(i) - _check_filename(dir_stack, name) - cwd[name] = value - for name,value in ( - record.variables['userVars'].items() + - record.variables['userStrs'].items()): - _check_filename(dir_stack, name) - cwd[name] = value - if record.variables['header']['version'] == 2: - raise NotImplementedError('add dependent variables to filesystem') diff --git a/igor/record/variables.py b/igor/record/variables.py index e55d800..d604bfd 100644 --- a/igor/record/variables.py +++ b/igor/record/variables.py @@ -1,34 +1,135 @@ # Copyright +import io as _io + +from .. import LOG as _LOG from ..binarywave import TYPE_TABLE as _TYPE_TABLE +from ..binarywave import NullStaticStringField as _NullStaticStringField +from ..binarywave import DynamicStringField as _DynamicStringField from ..struct import Structure as _Structure +from ..struct import DynamicStructure as _DynamicStructure from ..struct import Field as _Field +from ..struct import DynamicField as _DynamicField from ..util import byte_order as _byte_order from ..util import need_to_reorder_bytes as _need_to_reorder_bytes from .base import Record -VarHeaderCommon = _Structure( - name='VarHeaderCommon', - fields=[ - _Field('h', 'version', help='Version number for this header.'), - ]) +class ListedStaticStringField (_NullStaticStringField): + """Handle string conversions for multi-count dynamic parents. + + If a field belongs to a multi-count dynamic parent, the parent is + called multiple times to parse each count, and the field's + post-unpack hook gets called after the field is unpacked during + each iteration. This requires alternative logic for getting and + setting the string data. The actual string formatting code is not + affected. + """ + def post_unpack(self, parents, data): + parent_structure = parents[-1] + parent_data = self._get_structure_data(parents, data, parent_structure) + d = self._normalize_string(parent_data[-1][self.name]) + parent_data[-1][self.name] = d + + +class ListedStaticStringField (_NullStaticStringField): + """Handle string conversions for multi-count dynamic parents. + + If a field belongs to a multi-count dynamic parent, the parent is + called multiple times to parse each count, and the field's + post-unpack hook gets called after the field is unpacked during + each iteration. This requires alternative logic for getting and + setting the string data. The actual string formatting code is not + affected. + """ + def post_unpack(self, parents, data): + parent_structure = parents[-1] + parent_data = self._get_structure_data(parents, data, parent_structure) + d = self._normalize_string(parent_data[-1][self.name]) + parent_data[-1][self.name] = d + + +class ListedDynamicStrDataField (_DynamicStringField, ListedStaticStringField): + _size_field = 'strLen' + _null_terminated = False + + def _get_size_data(self, parents, data): + parent_structure = parents[-1] + parent_data = self._get_structure_data(parents, data, parent_structure) + return parent_data[-1][self._size_field] + + +class DynamicVarDataField (_DynamicField): + def pre_pack(self, parents, data): + raise NotImplementedError() + + def post_unpack(self, parents, data): + var_structure = parents[-1] + var_data = self._get_structure_data(parents, data, var_structure) + data = var_data[self.name] + d = {} + for i,value in enumerate(data): + key,value = self._normalize_item(i, value) + d[key] = value + var_data[self.name] = d + + def _normalize_item(self, index, value): + raise NotImplementedError() + + +class DynamicSysVarField (DynamicVarDataField): + def _normalize_item(self, index, value): + name = 'K{}'.format(index) + return (name, value) + + +class DynamicUserVarField (DynamicVarDataField): + def _normalize_item(self, index, value): + name = value['name'] + value = value['num'] + return (name, value) + + +class DynamicUserStrField (DynamicVarDataField): + def _normalize_item(self, index, value): + name = value['name'] + value = value['data'] + return (name, value) + + +class DynamicVarNumField (_DynamicField): + def post_unpack(self, parents, data): + parent_structure = parents[-1] + parent_data = self._get_structure_data(parents, data, parent_structure) + d = self._normalize_numeric_variable(parent_data[-1][self.name]) + parent_data[-1][self.name] = d + + def _normalize_numeric_variable(self, num_var): + t = _TYPE_TABLE[num_var['numType']] + if num_var['numType'] % 2: # complex number + return t(complex(num_var['realPart'], num_var['imagPart'])) + else: + return t(num_var['realPart']) + + +class DynamicFormulaField (_DynamicStringField): + _size_field = 'formulaLen' + _null_terminated = True + # From Variables.h -VarHeader1 = _Structure( +VarHeader1 = _Structure( # `version` field pulled out into VariablesRecord name='VarHeader1', fields=[ - _Field('h', 'version', help='Version number is 1 for this header.'), _Field('h', 'numSysVars', help='Number of system variables (K0, K1, ...).'), _Field('h', 'numUserVars', help='Number of user numeric variables -- may be zero.'), _Field('h', 'numUserStrs', help='Number of user string variables -- may be zero.'), ]) # From Variables.h -VarHeader2 = _Structure( +VarHeader2 = _Structure( # `version` field pulled out into VariablesRecord name='VarHeader2', fields=[ - _Field('h', 'version', help='Version number is 2 for this header.'), _Field('h', 'numSysVars', help='Number of system variables (K0, K1, ...).'), _Field('h', 'numUserVars', help='Number of user numeric variables -- may be zero.'), _Field('h', 'numUserStrs', help='Number of user string variables -- may be zero.'), @@ -37,19 +138,19 @@ VarHeader2 = _Structure( ]) # From Variables.h -UserStrVarRec1 = _Structure( +UserStrVarRec1 = _DynamicStructure( name='UserStrVarRec1', fields=[ - _Field('c', 'name', help='Name of the string variable.', count=32), + ListedStaticStringField('c', 'name', help='Name of the string variable.', count=32), _Field('h', 'strLen', help='The real size of the following array.'), - _Field('c', 'data'), + ListedDynamicStrDataField('c', 'data'), ]) # From Variables.h -UserStrVarRec2 = _Structure( +UserStrVarRec2 = _DynamicStructure( name='UserStrVarRec2', fields=[ - _Field('c', 'name', help='Name of the string variable.', count=32), + ListedStaticStringField('c', 'name', help='Name of the string variable.', count=32), _Field('l', 'strLen', help='The real size of the following array.'), _Field('c', 'data'), ]) @@ -65,146 +166,134 @@ VarNumRec = _Structure( ]) # From Variables.h -UserNumVarRec = _Structure( +UserNumVarRec = _DynamicStructure( name='UserNumVarRec', fields=[ - _Field('c', 'name', help='Name of the string variable.', count=32), + ListedStaticStringField('c', 'name', help='Name of the string variable.', count=32), _Field('h', 'type', help='0 = string, 1 = numeric.'), - _Field(VarNumRec, 'num', help='Type and value of the variable if it is numeric. Not used for string.'), + DynamicVarNumField(VarNumRec, 'num', help='Type and value of the variable if it is numeric. Not used for string.'), ]) # From Variables.h -UserDependentVarRec = _Structure( +UserDependentVarRec = _DynamicStructure( name='UserDependentVarRec', fields=[ - _Field('c', 'name', help='Name of the string variable.', count=32), + ListedStaticStringField('c', 'name', help='Name of the string variable.', count=32), _Field('h', 'type', help='0 = string, 1 = numeric.'), _Field(VarNumRec, 'num', help='Type and value of the variable if it is numeric. Not used for string.'), _Field('h', 'formulaLen', help='The length of the dependency formula.'), - _Field('c', 'formula', help='Start of the dependency formula. A C string including null terminator.'), + DynamicFormulaField('c', 'formula', help='Start of the dependency formula. A C string including null terminator.'), ]) -class VariablesRecord (Record): - def __init__(self, *args, **kwargs): - super(VariablesRecord, self).__init__(*args, **kwargs) - # self.header['version'] # record version always 0? - version = self._set_byte_order_and_get_version() - self.structure = self._get_structure(version) - self.variables = self.structure.unpack_from(self.data) - self.variables.update(self._unpack_variable_length_structures(version)) - self._normalize_variables() - - def _set_byte_order_and_get_version(self): - if self.byte_order: - VarHeaderCommon.set_byte_order(self.byte_order) - else: - VarHeaderCommon.set_byte_order('=') - version = VarHeaderCommon.unpack_from(self.data)['version'] - if not self.byte_order: - need_to_reorder = _need_to_reorder_bytes(version) - self.byte_order = _byte_order(need_to_reorder) - if need_to_reorder: - VarHeaderCommon.set_byte_order(self.byte_order) - version = VarHeaderCommon.unpack_from(self.data)['version'] - return version - - def _get_structure(self, version): - if version == 1: - header_struct = VarHeader1 - elif version == 2: - header_struct = VarHeader2 +class DynamicVarHeaderField (_DynamicField): + def pre_pack(self, parents, data): + raise NotImplementedError() + + def post_unpack(self, parents, data): + var_structure = parents[-1] + var_data = self._get_structure_data( + parents, data, var_structure) + var_header_structure = self.format + data = var_data['var_header'] + sys_vars_field = var_structure.get_field('sysVars') + sys_vars_field.count = data['numSysVars'] + sys_vars_field.setup() + user_vars_field = var_structure.get_field('userVars') + user_vars_field.count = data['numUserVars'] + user_vars_field.setup() + user_strs_field = var_structure.get_field('userStrs') + user_strs_field.count = data['numUserStrs'] + user_strs_field.setup() + if 'numDependentVars' in data: + dependent_vars_field = var_structure.get_field('dependentVars') + dependent_vars_field.count = data['numDependentVars'] + dependent_vars_field.setup() + dependent_strs_field = var_structure.get_field('dependentStrs') + dependent_strs_field.count = data['numDependentStrs'] + dependent_strs_field.setup() + var_structure.setup() + + +Variables1 = _DynamicStructure( + name='Variables1', + fields=[ + DynamicVarHeaderField(VarHeader1, 'var_header', help='Variables header'), + DynamicSysVarField('f', 'sysVars', help='System variables', count=0), + DynamicUserVarField(UserNumVarRec, 'userVars', help='User numeric variables', count=0), + DynamicUserStrField(UserStrVarRec1, 'userStrs', help='User string variables', count=0), + ]) + + +Variables2 = _DynamicStructure( + name='Variables2', + fields=[ + DynamicVarHeaderField(VarHeader2, 'var_header', help='Variables header'), + DynamicSysVarField('f', 'sysVars', help='System variables', count=0), + DynamicUserVarField(UserNumVarRec, 'userVars', help='User numeric variables', count=0), + DynamicUserStrField(UserStrVarRec2, 'userStrs', help='User string variables', count=0), + _Field(UserDependentVarRec, 'dependentVars', help='Dependent numeric variables.', count=0), + _Field(UserDependentVarRec, 'dependentStrs', help='Dependent string variables.', count=0), + ]) + + +class DynamicVersionField (_DynamicField): + def pre_pack(self, parents, byte_order): + raise NotImplementedError() + + def post_unpack(self, parents, data): + variables_structure = parents[-1] + variables_data = self._get_structure_data( + parents, data, variables_structure) + version = variables_data['version'] + if variables_structure.byte_order in '@=': + need_to_reorder_bytes = _need_to_reorder_bytes(version) + variables_structure.byte_order = _byte_order(need_to_reorder_bytes) + _LOG.debug( + 'get byte order from version: {} (reorder? {})'.format( + variables_structure.byte_order, need_to_reorder_bytes)) else: - raise NotImplementedError( - 'Variables record version {}'.format(version)) - header = header_struct.unpack_from(self.data) - fields = [ - _Field(header_struct, 'header', help='VarHeader'), - _Field('f', 'sysVars', help='system variables', - count=header['numSysVars']), - _Field(UserNumVarRec, 'userVars', help='user variables', - count=header['numUserVars']), - ] - return _Structure(name='variables', fields=fields) - - def _unpack_variable_length_structures(self, version): - data = {'userStrs': []} - offset = self.structure.size + need_to_reorder_bytes = False + old_format = variables_structure.fields[-1].format if version == 1: - user_str_var_struct = UserStrVarRec1 + variables_structure.fields[-1].format = Variables1 elif version == 2: - user_str_var_struct = UserStrVarRec2 - else: - raise NotImplementedError( - 'Variables record version {}'.format(version)) - user_str_var_struct.set_byte_order(self.byte_order) - for i in range(self.variables['header']['numUserStrs']): - d = user_str_var_struct.unpack_from(self.data, offset) - offset += user_str_var_struct.size - end = offset + d['strLen'] - 1 # one character already in struct - if d['strLen']: - d['data'] = d['data'] + self.data[offset:end] - else: - d['data'] = '' - offset = end - data['userStrs'].append(d) - - if version == 2: - data.update({'dependentVars': [], 'dependentStrs': []}) - UserDependentVarRec.set_byte_order(self.byte_order) - for i in range(self.variables['header']['numDependentVars']): - d,offset = self._unpack_dependent_variable(offset) - data['dependentVars'].append(d) - for i in range(self.variables['header']['numDependentStrs']): - d,offset = self._unpack_dependent_variable(offset) - data['dependentStrs'].append(d) - - if offset != len(self.data): - raise ValueError('too much data ({} extra bytes)'.format( - len(self.data)-offset)) - return data - - def _unpack_dependent_variable(self, offset): - d = UserDependentVarRec.unpack_from(self.data, offset) - offset += UserDependentVarRec.size - end = offset + d['formulaLen'] - 1 # one character already in struct - if d['formulaLen']: - d['formula'] = d['formula'] + self.data[offset:end] - else: - d['formula'] = '' - offset = end - return (d, offset) - - def _normalize_variables(self): - user_vars = {} - for num_var in self.variables['userVars']: - key,value = self._normalize_user_numeric_variable(num_var) - user_vars[key] = value - self.variables['userVars'] = user_vars - user_strs = {} - for str_var in self.variables['userStrs']: - name = self._normalize_null_terminated_string(str_var['name']) - user_strs[name] = str_var['data'] - if self.variables['header']['version'] == 2: - raise NotImplementedError('normalize dependent variables') - self.variables['userStrs'] = user_strs - - def _normalize_null_terminated_string(self, string): - return string.tostring().split('\x00', 1)[0] - - def _normalize_user_numeric_variable(self, user_num_var): - user_num_var['name'] = self._normalize_null_terminated_string( - user_num_var['name']) - if user_num_var['type']: # numeric - value = self._normalize_numeric_variable(user_num_var['num']) - else: # string - value = None - return (user_num_var['name'], value) + variables_structure.fields[-1].format = Variables2 + elif not need_to_reorder_bytes: + raise ValueError( + 'invalid variables record version: {}'.format(version)) - def _normalize_numeric_variable(self, num_var): - t = _TYPE_TABLE[num_var['numType']] - if num_var['numType'] % 2: # complex number - return t(complex(num_var['realPart'], num_var['imagPart'])) - else: - return t(num_var['realPart']) + if variables_structure.fields[-1].format != old_format: + _LOG.debug('change variables record from {} to {}'.format( + old_format, variables_structure.fields[-1].format)) + variables_structure.setup() + elif need_to_reorder_bytes: + variables_structure.setup() + + # we might need to unpack again with the new byte order + return need_to_reorder_bytes + + +VariablesRecordStructure = _DynamicStructure( + name='VariablesRecord', + fields=[ + DynamicVersionField('h', 'version', help='Version number for this header.'), + _Field(Variables1, 'variables', help='The rest of the variables data.'), + ]) + + +class VariablesRecord (Record): + def __init__(self, *args, **kwargs): + super(VariablesRecord, self).__init__(*args, **kwargs) + # self.header['version'] # record version always 0? + VariablesRecordStructure.byte_order = '=' + VariablesRecordStructure.setup() + stream = _io.BytesIO(bytes(self.data)) + self.variables = VariablesRecordStructure.unpack_stream(stream) + self.namespace = {} + for key,value in self.variables['variables'].items(): + if key not in ['var_header']: + _LOG.debug('update namespace {} with {} for {}'.format( + self.namespace, value, key)) + self.namespace.update(value) diff --git a/igor/record/wave.py b/igor/record/wave.py index 93de8a3..db36cfa 100644 --- a/igor/record/wave.py +++ b/igor/record/wave.py @@ -9,8 +9,7 @@ from . import Record class WaveRecord (Record): def __init__(self, *args, **kwargs): super(WaveRecord, self).__init__(*args, **kwargs) - self.wave,self.bin_info,self.wave_info = _loadibw( - _BytesIO(bytes(self.data)), strict=False) + self.wave = _loadibw(_BytesIO(bytes(self.data))) def __str__(self): return str(self.wave) diff --git a/igor/struct.py b/igor/struct.py index c9886a0..fce93b5 100644 --- a/igor/struct.py +++ b/igor/struct.py @@ -9,10 +9,15 @@ with each field in a hierarchy of Python dictionaries. """ from __future__ import absolute_import +import io as _io +import logging as _logging +import pprint as _pprint import struct as _struct import numpy as _numpy +from . import LOG as _LOG + _buffer = buffer # save builtin buffer for clobbered situations @@ -34,7 +39,7 @@ class Field (object): >>> time = Field( ... 'I', 'time', default=0, help='POSIX time') - >>> time.total_count + >>> time.arg_count 1 >>> list(time.pack_data(1)) [1] @@ -49,7 +54,7 @@ class Field (object): >>> data = Field( ... 'f', 'data', help='example data', count=(2,3,4)) - >>> data.total_count + >>> data.arg_count 24 >>> list(data.indexes()) # doctest: +ELLIPSIS [[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 0, 3], [0, 1, 0], ..., [1, 2, 3]] @@ -60,7 +65,7 @@ class Field (object): [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ..., 19, 20, 21, 22, 23] >>> list(data.pack_item(3)) [3] - >>> data.unpack_data(range(data.total_count)) + >>> data.unpack_data(range(data.arg_count)) array([[[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]], @@ -75,10 +80,10 @@ class Field (object): >>> run = Structure('run', fields=[time, data]) >>> runs = Field(run, 'runs', help='pair of runs', count=2) - >>> runs.total_count # = 2 * (1 + 24) + >>> runs.arg_count # = 2 * (1 + 24) 50 - >>> data1 = numpy.arange(data.total_count).reshape(data.count) - >>> data2 = data1 + data.total_count + >>> data1 = numpy.arange(data.arg_count).reshape(data.count) + >>> data2 = data1 + data.arg_count >>> list(runs.pack_data( ... [{'time': 100, 'data': data1}, ... {'time': 101, 'data': data2}]) @@ -87,7 +92,7 @@ class Field (object): >>> list(runs.pack_item({'time': 100, 'data': data1}) ... ) # doctest: +ELLIPSIS [100, 0, 1, 2, ..., 22, 23] - >>> pprint(runs.unpack_data(range(runs.total_count))) + >>> pprint(runs.unpack_data(range(runs.arg_count))) [{'data': array([[[ 1, 2, 3, 4], [ 5, 6, 7, 8], [ 9, 10, 11, 12]], @@ -137,12 +142,24 @@ class Field (object): self.default = default self.help = help self.count = count - self.item_count = _numpy.prod(count) # number of item repeats + self.setup() + + def setup(self): + """Setup any dynamic properties of a field. + + Use this method to recalculate dynamic properities after + changing the basic properties set during initialization. + """ + _LOG.debug('setup {}'.format(self)) + self.item_count = _numpy.prod(self.count) # number of item repeats if isinstance(self.format, Structure): - self.structure_count = sum(f.total_count for f in format.fields) - self.total_count = self.item_count * self.structure_count + self.structure_count = sum( + f.arg_count for f in self.format.fields) + self.arg_count = self.item_count * self.structure_count + elif self.format == 'x': + self.arg_count = 0 # no data in padding bytes else: - self.total_count = self.item_count # struct.Struct format chars + self.arg_count = self.item_count # struct.Struct format args def __str__(self): return self.__repr__() @@ -220,9 +237,10 @@ class Field (object): def unpack_data(self, data): """Inverse of .pack_data""" + _LOG.debug('unpack {} for {} {}'.format(data, self, self.format)) iterator = iter(data) try: - items = [iterator.next() for i in range(self.total_count)] + items = [iterator.next() for i in range(self.arg_count)] except StopIteration: raise ValueError('not enough data to unpack {}'.format(self)) try: @@ -238,7 +256,11 @@ class Field (object): else: items = [[i] for i in items] unpacked = [self.unpack_item(i) for i in items] - if self.count == 1: + if self.arg_count: + count = self.count + else: + count = 0 # padding bytes, etc. + if count == 1: return unpacked[0] if isinstance(self.format, Structure): try: @@ -249,10 +271,12 @@ class Field (object): raise NotImplementedError('reshape Structure field') else: unpacked = _numpy.array(unpacked) - unpacked = unpacked.reshape(self.count) + _LOG.debug('reshape {} data from {} to {}'.format( + self, unpacked.shape, count)) + unpacked = unpacked.reshape(count) return unpacked - def unpack_item(self, item): + def unpack_item(self, item): """Inverse of .unpack_item""" if isinstance(self.format, Structure): return self.format._unpack_item(item) @@ -261,6 +285,54 @@ class Field (object): return item[0] +class DynamicField (Field): + """Represent a DynamicStructure field with a dynamic definition. + + Adds the methods ``.pre_pack``, ``pre_unpack``, and + ``post_unpack``, all of which are called when a ``DynamicField`` + is used by a ``DynamicStructure``. Each method takes the + arguments ``(parents, data)``, where ``parents`` is a list of + ``DynamicStructure``\s that own the field and ``data`` is a dict + hierarchy of the structure data. + + See the ``DynamicStructure`` docstring for the exact timing of the + method calls. + + See Also + -------- + Field, DynamicStructure + """ + def pre_pack(self, parents, data): + "Prepare to pack." + pass + + def pre_unpack(self, parents, data): + "React to previously unpacked data" + pass + + def post_unpack(self, parents, data): + "React to our own data" + pass + + def _get_structure_data(self, parents, data, structure): + """Extract the data belonging to a particular ancestor structure. + """ + d = data + s = parents[0] + if s == structure: + return d + for p in parents[1:]: + for f in s.fields: + if f.format == p: + s = p + d = d[f.name] + break + assert s == p, (s, p) + if p == structure: + break + return d + + class Structure (_struct.Struct): r"""Represent a C structure. @@ -289,7 +361,7 @@ class Structure (_struct.Struct): struct run runs[2]; } - As + As: >>> time = Field('I', 'time', default=0, help='POSIX time') >>> data = Field( @@ -303,19 +375,30 @@ class Structure (_struct.Struct): The structures automatically calculate the flattened data format: >>> run.format - '=Ihhhhhh' + '@Ihhhhhh' >>> run.size # 4 + 2*3*2 16 >>> experiment.format - '=HIhhhhhhIhhhhhh' - >>> experiment.size # 2 + 2*(4 + 2*3*2) + '@HIhhhhhhIhhhhhh' + >>> experiment.size # 2 + 2 + 2*(4 + 2*3*2) + 36 + + The first two elements in the above size calculation are 2 (for + the unsigned short, 'H') and 2 (padding so the unsigned int aligns + with a 4-byte block). If you select a byte ordering that doesn't + mess with alignment and recalculate the format, the padding goes + away and you get: + + >>> experiment.set_byte_order('>') + >>> experiment.get_format() + '>HIhhhhhhIhhhhhh' + >>> experiment.size 34 You can read data out of any object supporting the buffer interface: >>> b = array.array('B', range(experiment.size)) - >>> experiment.set_byte_order('>') >>> d = experiment.unpack_from(buffer=b) >>> pprint(d) {'runs': [{'data': array([[1543, 2057, 2571], @@ -375,12 +458,15 @@ class Structure (_struct.Struct): >>> b2 == b True """ - def __init__(self, name, fields, byte_order='='): + _byte_order_symbols = '@=<>!' + + def __init__(self, name, fields, byte_order='@'): # '=' for native byte order, standard size and alignment # See http://docs.python.org/library/struct for details self.name = name self.fields = fields - self.set_byte_order(byte_order) + self.byte_order = byte_order + self.setup() def __str__(self): return self.name @@ -389,25 +475,46 @@ class Structure (_struct.Struct): return '<{} {} {}>'.format( self.__class__.__name__, self.name, id(self)) + def setup(self): + """Setup any dynamic properties of a structure. + + Use this method to recalculate dynamic properities after + changing the basic properties set during initialization. + """ + _LOG.debug('setup {!r}'.format(self)) + self.set_byte_order(self.byte_order) + self.get_format() + def set_byte_order(self, byte_order): """Allow changing the format byte_order on the fly. """ - if (hasattr(self, 'format') and self.format != None - and self.format.startswith(byte_order)): - return # no need to change anything - format = [] + _LOG.debug('set byte order for {!r} to {}'.format(self, byte_order)) + self.byte_order = byte_order for field in self.fields: if isinstance(field.format, Structure): - field_format = field.format.sub_format( - ) * field.item_count - else: - field_format = [field.format]*field.item_count - format.extend(field_format) - super(Structure, self).__init__( - format=byte_order+''.join(format).replace('P', 'L')) + field.format.set_byte_order(byte_order) + + def get_format(self): + format = self.byte_order + ''.join(self.sub_format()) + # P format only allowed for native byte ordering + # Convert P to I for ILP32 compatibility when running on a LP64. + format = format.replace('P', 'I') + try: + super(Structure, self).__init__(format=format) + except _struct.error as e: + raise ValueError((e, format)) + return format def sub_format(self): - return self.format.lstrip('=<>') # byte order handled by parent + _LOG.debug('calculate sub-format for {!r}'.format(self)) + for field in self.fields: + if isinstance(field.format, Structure): + field_format = list( + field.format.sub_format()) * field.item_count + else: + field_format = [field.format]*field.item_count + for fmt in field_format: + yield fmt def _pack_item(self, item=None): """Linearize a single count of the structure's data to a flat iterable @@ -430,7 +537,7 @@ class Structure (_struct.Struct): iterator = iter(args) for f in self.fields: try: - items = [iterator.next() for i in range(f.total_count)] + items = [iterator.next() for i in range(f.arg_count)] except StopIteration: raise ValueError('not enough data to unpack {}.{}'.format( self, f)) @@ -445,7 +552,10 @@ class Structure (_struct.Struct): def pack(self, data): args = list(self._pack_item(data)) - return super(Structure, self).pack(*args) + try: + return super(Structure, self).pack(*args) + except: + raise ValueError(self.format) def pack_into(self, buffer, offset=0, data={}): args = list(self._pack_item(data)) @@ -457,20 +567,247 @@ class Structure (_struct.Struct): return self._unpack_item(args) def unpack_from(self, buffer, offset=0, *args, **kwargs): - try: - args = super(Structure, self).unpack_from( - buffer, offset, *args, **kwargs) - except _struct.error as e: - if not self.name in ('WaveHeader2', 'WaveHeader5'): - raise - # HACK! For WaveHeader5, when npnts is 0, wData is - # optional. If we couldn't unpack the structure, fill in - # wData with zeros and try again, asserting that npnts is - # zero. - if len(buffer) - offset < self.size: - # missing wData? Pad with zeros - buffer += _buffer('\x00'*(self.size + offset - len(buffer))) - args = super(Structure, self).unpack_from(buffer, offset) - data = self._unpack_item(args) - assert data['npnts'] == 0, data['npnts'] + _LOG.debug( + 'unpack {!r} for {!r} ({}, offset={}) with {} ({})'.format( + buffer, self, len(buffer), offset, self.format, self.size)) + args = super(Structure, self).unpack_from( + buffer, offset, *args, **kwargs) + return self._unpack_item(args) + + def get_field(self, name): + return [f for f in self.fields if f.name == name][0] + + +class DebuggingStream (object): + def __init__(self, stream): + self.stream = stream + + def read(self, size): + data = self.stream.read(size) + _LOG.debug('read {} from {}: ({}) {!r}'.format( + size, self.stream, len(data), data)) + return data + + +class DynamicStructure (Structure): + r"""Represent a C structure field with a dynamic definition. + + Any dynamic fields have their ``.pre_pack`` called before any + structure packing is done. ``.pre_unpack`` is called for a + particular field just before that field's ``.unpack_data`` call. + ``.post_unpack`` is called for a particular field just after + ``.unpack_data``. If ``.post_unpack`` returns ``True``, the same + field is unpacked again. + + Examples + -------- + + >>> from pprint import pprint + + This allows you to define structures where some portion of the + global structure depends on earlier data. For example, in the + quasi-C structure:: + + struct vector { + unsigned int length; + short data[length]; + } + + You can generate a Python version of this structure in two ways, + with a dynamic ``length``, or with a dynamic ``data``. In both + cases, the required methods are the same, the only difference is + where you attach them. + + >>> def packer(self, parents, data): + ... vector_structure = parents[-1] + ... vector_data = self._get_structure_data( + ... parents, data, vector_structure) + ... length = len(vector_data['data']) + ... vector_data['length'] = length + ... data_field = vector_structure.get_field('data') + ... data_field.count = length + ... data_field.setup() + >>> def unpacker(self, parents, data): + ... vector_structure = parents[-1] + ... vector_data = self._get_structure_data( + ... parents, data, vector_structure) + ... length = vector_data['length'] + ... data_field = vector_structure.get_field('data') + ... data_field.count = length + ... data_field.setup() + + >>> class DynamicLengthField (DynamicField): + ... def pre_pack(self, parents, data): + ... packer(self, parents, data) + ... def post_unpack(self, parents, data): + ... unpacker(self, parents, data) + >>> dynamic_length_vector = DynamicStructure('vector', + ... fields=[ + ... DynamicLengthField('I', 'length'), + ... Field('h', 'data', count=0), + ... ], + ... byte_order='>') + >>> class DynamicDataField (DynamicField): + ... def pre_pack(self, parents, data): + ... packer(self, parents, data) + ... def pre_unpack(self, parents, data): + ... unpacker(self, parents, data) + >>> dynamic_data_vector = DynamicStructure('vector', + ... fields=[ + ... Field('I', 'length'), + ... DynamicDataField('h', 'data', count=0), + ... ], + ... byte_order='>') + + >>> b = '\x00\x00\x00\x02\x01\x02\x03\x04' + >>> d = dynamic_length_vector.unpack(b) + >>> pprint(d) + {'data': array([258, 772]), 'length': 2} + >>> d = dynamic_data_vector.unpack(b) + >>> pprint(d) + {'data': array([258, 772]), 'length': 2} + + >>> d['data'] = [1,2,3,4] + >>> dynamic_length_vector.pack(d) + '\x00\x00\x00\x04\x00\x01\x00\x02\x00\x03\x00\x04' + >>> dynamic_data_vector.pack(d) + '\x00\x00\x00\x04\x00\x01\x00\x02\x00\x03\x00\x04' + + The implementation is a good deal more complicated than the one + for ``Structure``, because we must make multiple calls to + ``struct.Struct.unpack`` to unpack the data. + """ + #def __init__(self, *args, **kwargs): + # pass #self.parent = .. + + def _pre_pack(self, parents=None, data=None): + if parents is None: + parents = [self] + else: + parents = parents + [self] + for f in self.fields: + if hasattr(f, 'pre_pack'): + _LOG.debug('pre-pack {}'.format(f)) + f.pre_pack(parents=parents, data=data) + if isinstance(f.format, DynamicStructure): + _LOG.debug('pre-pack {!r}'.format(f.format)) + f._pre_pack(parents=parents, data=data) + + def pack(self, data): + self._pre_pack(data=data) + self.setup() + return super(DynamicStructure, self).pack(data) + + def pack_into(self, buffer, offset=0, data={}): + self._pre_pack(data=data) + self.setup() + return super(DynamicStructure, self).pack_into( + buffer=buffer, offset=offset, data=data) + + def unpack_stream(self, stream, parents=None, data=None, d=None): + # `d` is the working data directory + if data is None: + parents = [self] + data = d = {} + if _LOG.level == _logging.DEBUG: + stream = DebuggingStream(stream) + else: + parents = parents + [self] + + for f in self.fields: + _LOG.debug('parsing {!r}.{} (count={}, item_count={})'.format( + self, f, f.count, f.item_count)) + _LOG.debug('data:\n{}'.format(_pprint.pformat(data))) + if hasattr(f, 'pre_unpack'): + _LOG.debug('pre-unpack {}'.format(f)) + f.pre_unpack(parents=parents, data=data) + + if hasattr(f, 'unpack'): # override default unpacking + _LOG.debug('override unpack for {}'.format(f)) + d[f.name] = f.unpack(stream) + continue + + # setup for unpacking loop + if isinstance(f.format, Structure): + f.format.set_byte_order(self.byte_order) + f.setup() + f.format.setup() + if isinstance(f.format, DynamicStructure): + if f.item_count == 1: + # TODO, fix in case we *want* an array + d[f.name] = {} + f.format.unpack_stream( + stream, parents=parents, data=data, d=d[f.name]) + else: + d[f.name] = [] + for i in range(f.item_count): + x = {} + d[f.name].append(x) + f.format.unpack_stream( + stream, parents=parents, data=data, d=x) + if hasattr(f, 'post_unpack'): + _LOG.debug('post-unpack {}'.format(f)) + repeat = f.post_unpack(parents=parents, data=data) + if repeat: + raise NotImplementedError( + 'cannot repeat unpack for dynamic structures') + continue + if isinstance(f.format, Structure): + _LOG.debug('parsing {} bytes for {}'.format( + f.format.size, f.format.format)) + bs = [stream.read(f.format.size) for i in range(f.item_count)] + def unpack(): + f.format.set_byte_order(self.byte_order) + f.setup() + f.format.setup() + x = [f.format.unpack_from(b) for b in bs] + if len(x) == 1: # TODO, fix in case we *want* an array + x = x[0] + return x + else: + field_format = self.byte_order + f.format*f.item_count + field_format = field_format.replace('P', 'I') + try: + size = _struct.calcsize(field_format) + except _struct.error as e: + _LOG.error(e) + _LOG.error('{}.{}: {}'.format(self, f, field_format)) + raise + _LOG.debug('parsing {} bytes for preliminary {}'.format( + size, field_format)) + raw = stream.read(size) + if len(raw) < size: + raise ValueError( + 'not enough data to unpack {}.{} ({} < {})'.format( + self, f, len(raw), size)) + def unpack(): + field_format = self.byte_order + f.format*f.item_count + field_format = field_format.replace('P', 'I') + _LOG.debug('parse previous bytes using {}'.format( + field_format)) + struct = _struct.Struct(field_format) + items = struct.unpack(raw) + return f.unpack_data(items) + + # unpacking loop + repeat = True + while repeat: + d[f.name] = unpack() + if hasattr(f, 'post_unpack'): + _LOG.debug('post-unpack {}'.format(f)) + repeat = f.post_unpack(parents=parents, data=data) + else: + repeat = False + if repeat: + _LOG.debug('repeat unpack for {}'.format(f)) + + return data + + def unpack(self, string): + stream = _io.BytesIO(string) + return self.unpack_stream(stream) + + def unpack_from(self, buffer, offset=0, *args, **kwargs): + args = super(Structure, self).unpack_from( + buffer, offset, *args, **kwargs) return self._unpack_item(args) diff --git a/test/test.py b/test/test.py index af65c79..1567ff3 100644 --- a/test/test.py +++ b/test/test.py @@ -2,595 +2,571 @@ r"""Test the igor module by loading sample files. ->>> dumpibw('mac-double.ibw', strict=False) # doctest: +REPORT_UDIFF -array([ 5., 4., 3., 2., 1.]) -{'checksum': 25137, - 'note': '', - 'noteSize': 0, - 'pictSize': 0, - 'version': 2, - 'wfmSize': 166} -{'aModified': 0, - 'bname': array(['d', 'o', 'u', 'b', 'l', 'e', '', '', '', '', '', '', '', '', '', - '', '', '', '', ''], - dtype='|S1'), - 'botFullScale': 0.0, - 'creationDate': 3001587842, - 'dataUnits': array(['', '', '', ''], - dtype='|S1'), - 'depID': 0, - 'fileName': 0, - 'formula': 0, - 'fsValid': 0, - 'hsA': 1.0, - 'hsB': 0.0, - 'kindBits': '\x00', - 'modDate': 3001587842, - 'next': 0, - 'npnts': 5, - 'srcFldr': 0, - 'swModified': 0, - 'topFullScale': 0.0, - 'type': 4, - 'useBits': '\x00', - 'wData': array([ 2.3125, 0. , 2.25 , 0. ]), - 'wModified': 0, - 'wUnused': array(['', ''], - dtype='|S1'), - 'waveNoteH': 0, - 'whVersion': 0, - 'xUnits': array(['', '', '', ''], - dtype='|S1')} +>>> dumpibw('mac-double.ibw') # doctest: +REPORT_UDIFF +{'version': 2, + 'wave': {'bin_header': {'checksum': 25137, + 'noteSize': 0, + 'pictSize': 0, + 'wfmSize': 166}, + 'note': '', + 'padding': array([], dtype=float64), + 'wData': array([ 5., 4., 3., 2., 1.]), + 'wave_header': {'aModified': 0, + 'bname': 'double', + 'botFullScale': 0.0, + 'creationDate': 3001587842, + 'dataUnits': array(['', '', '', ''], + dtype='|S1'), + 'depID': 0, + 'fileName': 0, + 'formula': 0, + 'fsValid': 0, + 'hsA': 1.0, + 'hsB': 0.0, + 'kindBits': '\x00', + 'modDate': 3001587842, + 'next': 0, + 'npnts': 5, + 'srcFldr': 0, + 'swModified': 0, + 'topFullScale': 0.0, + 'type': 4, + 'useBits': '\x00', + 'wModified': 0, + 'wUnused': array(['', ''], + dtype='|S1'), + 'waveNoteH': 0, + 'whVersion': 0, + 'xUnits': array(['', '', '', ''], + dtype='|S1')}}} >>> dumpibw('mac-textWave.ibw') # doctest: +REPORT_UDIFF -array(['Mary', 'had', 'a', 'little', 'lamb'], - dtype='|S6') -{'checksum': 5554, - 'dataEUnits': '', - 'dataEUnitsSize': 0, - 'dimEUnits': ['', '', '', ''], - 'dimEUnitsSize': array([0, 0, 0, 0]), - 'dimLabels': [[], [], [], []], - 'dimLabelsSize': array([0, 0, 0, 0]), - 'formula': '', - 'formulaSize': 0, - 'note': '', - 'noteSize': 0, - 'optionsSize1': 0, - 'optionsSize2': 0, - 'sIndices': array([ 4, 7, 8, 14, 18], dtype=uint32), - 'sIndicesSize': 20, - 'version': 5, - 'wfmSize': 338} -{'aModified': 0, - 'bname': array(['t', 'e', 'x', 't', '0', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''], - dtype='|S1'), - 'botFullScale': 0.0, - 'creationDate': 3001571199, - 'dFolder': 69554896, - 'dLock': 0, - 'dataEUnits': 0, - 'dataUnits': array(['', '', '', ''], - dtype='|S1'), - 'depID': 22, - 'dimEUnits': array([0, 0, 0, 0]), - 'dimLabels': array([0, 0, 0, 0]), - 'dimUnits': array([['', '', '', ''], +{'version': 5, + 'wave': {'bin_header': {'checksum': 5554, + 'dataEUnitsSize': 0, + 'dimEUnitsSize': array([0, 0, 0, 0]), + 'dimLabelsSize': array([0, 0, 0, 0]), + 'formulaSize': 0, + 'noteSize': 0, + 'optionsSize1': 0, + 'optionsSize2': 0, + 'sIndicesSize': 20, + 'wfmSize': 338}, + 'data_units': '', + 'dimension_units': '', + 'formula': '', + 'labels': [[], [], [], []], + 'note': '', + 'sIndices': array([ 4, 7, 8, 14, 18]), + 'wData': array(['Mary', 'had', 'a', 'little', 'lamb'], + dtype='|S6'), + 'wave_header': {'aModified': 0, + 'bname': 'text0', + 'botFullScale': 0.0, + 'creationDate': 3001571199, + 'dFolder': 69554896, + 'dLock': 0, + 'dataEUnits': 0, + 'dataUnits': array(['', '', '', ''], + dtype='|S1'), + 'depID': 22, + 'dimEUnits': array([0, 0, 0, 0]), + 'dimLabels': array([0, 0, 0, 0]), + 'dimUnits': array([['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']], dtype='|S1'), - 'fileName': 0, - 'formula': 0, - 'fsValid': 0, - 'kindBits': '\x00', - 'modDate': 3001571215, - 'nDim': array([5, 0, 0, 0]), - 'next': 0, - 'npnts': 5, - 'sIndices': 69557296, - 'sfA': array([ 1., 1., 1., 1.]), - 'sfB': array([ 0., 0., 0., 0.]), - 'srcFldr': 0, - 'swModified': 1, - 'topFullScale': 0.0, - 'type': 0, - 'useBits': '\x00', - 'wData': 236398480.0, - 'wModified': 0, - 'waveNoteH': 0, - 'whUnused': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - 'whVersion': 1, - 'whpad1': array(['', '', '', '', '', ''], - dtype='|S1'), - 'whpad2': 0, - 'whpad3': 0, - 'whpad4': 0} + 'fileName': 0, + 'formula': 0, + 'fsValid': 0, + 'kindBits': '\x00', + 'modDate': 3001571215, + 'nDim': array([5, 0, 0, 0]), + 'next': 0, + 'npnts': 5, + 'sIndices': 69557296, + 'sfA': array([ 1., 1., 1., 1.]), + 'sfB': array([ 0., 0., 0., 0.]), + 'srcFldr': 0, + 'swModified': 1, + 'topFullScale': 0.0, + 'type': 0, + 'useBits': '\x00', + 'wModified': 0, + 'waveNoteH': 0, + 'whUnused': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + 'whVersion': 1, + 'whpad1': array(['', '', '', '', '', ''], + dtype='|S1'), + 'whpad2': 0, + 'whpad3': 0, + 'whpad4': 0}}} ->>> dumpibw('mac-version2.ibw', strict=False) # doctest: +REPORT_UDIFF -array([ 5., 4., 3., 2., 1.], dtype=float32) -{'checksum': -16803, - 'note': 'This is a test.', - 'noteSize': 15, - 'pictSize': 0, - 'version': 2, - 'wfmSize': 146} -{'aModified': 0, - 'bname': array(['v', 'e', 'r', 's', 'i', 'o', 'n', '2', '', '', '', '', '', '', '', - '', '', '', '', ''], - dtype='|S1'), - 'botFullScale': 0.0, - 'creationDate': 3001251979, - 'dataUnits': array(['', '', '', ''], - dtype='|S1'), - 'depID': 0, - 'fileName': 0, - 'formula': 0, - 'fsValid': 0, - 'hsA': 1.0, - 'hsB': 0.0, - 'kindBits': '\x00', - 'modDate': 3001573594, - 'next': 0, - 'npnts': 5, - 'srcFldr': 0, - 'swModified': 0, - 'topFullScale': 0.0, - 'type': 2, - 'useBits': '\x00', - 'wData': array([ 5., 4., 3., 2.]), - 'wModified': 0, - 'wUnused': array(['', ''], - dtype='|S1'), - 'waveNoteH': 0, - 'whVersion': 0, - 'xUnits': array(['', '', '', ''], - dtype='|S1')} +>>> dumpibw('mac-version2.ibw') # doctest: +REPORT_UDIFF +{'version': 2, + 'wave': {'bin_header': {'checksum': -16803, + 'noteSize': 15, + 'pictSize': 0, + 'wfmSize': 146}, + 'note': 'This is a test.', + 'padding': array([], dtype=float64), + 'wData': array([ 5., 4., 3., 2., 1.], dtype=float32), + 'wave_header': {'aModified': 0, + 'bname': 'version2', + 'botFullScale': 0.0, + 'creationDate': 3001251979, + 'dataUnits': array(['', '', '', ''], + dtype='|S1'), + 'depID': 0, + 'fileName': 0, + 'formula': 0, + 'fsValid': 0, + 'hsA': 1.0, + 'hsB': 0.0, + 'kindBits': '\x00', + 'modDate': 3001573594, + 'next': 0, + 'npnts': 5, + 'srcFldr': 0, + 'swModified': 0, + 'topFullScale': 0.0, + 'type': 2, + 'useBits': '\x00', + 'wModified': 0, + 'wUnused': array(['', ''], + dtype='|S1'), + 'waveNoteH': 0, + 'whVersion': 0, + 'xUnits': array(['', '', '', ''], + dtype='|S1')}}} ->>> dumpibw('mac-version3Dependent.ibw', strict=False) # doctest: +REPORT_UDIFF -array([], dtype=int8) -{'checksum': 0, - 'formula': '', - 'formulaSize': 0, - 'note': '', - 'noteSize': 8257536, - 'pictSize': 262144, - 'version': 3, - 'wfmSize': 0} -{'aModified': 10, - 'bname': array(['', '', 'v', 'e', 'r', 's', 'i', 'o', 'n', '3', 'D', 'e', 'p', 'e', - 'n', 'd', 'e', 'n', 't', ''], - dtype='|S1'), - 'botFullScale': 0.0, - 'creationDate': 1507328, - 'dataUnits': array(['', '', '', ''], - dtype='|S1'), - 'depID': -487849984, - 'fileName': 0, - 'formula': 1577, - 'fsValid': 1, - 'hsA': 4.5193417557662e-309, - 'hsB': 0.0, - 'kindBits': '\x00', - 'modDate': 45801, - 'next': 131072, - 'npnts': 0, - 'srcFldr': 0, - 'swModified': 1, - 'topFullScale': 0.0, - 'type': -32334, - 'useBits': '\x00', - 'wData': array([ 0., 0., 0., 0.]), - 'wModified': 0, - 'wUnused': array(['', ''], - dtype='|S1'), - 'waveNoteH': 3835494400, - 'whVersion': 0, - 'xUnits': array(['', '', '', ''], - dtype='|S1')} +>>> dumpibw('mac-version3Dependent.ibw') # doctest: +REPORT_UDIFF +{'version': 3, + 'wave': {'bin_header': {'checksum': -32334, + 'formulaSize': 4, + 'noteSize': 0, + 'pictSize': 0, + 'wfmSize': 126}, + 'formula': ' K0', + 'note': '', + 'padding': array([], dtype=float64), + 'wData': array([], dtype=float32), + 'wave_header': {'aModified': 3, + 'bname': 'version3Dependent', + 'botFullScale': 0.0, + 'creationDate': 0, + 'dataUnits': array(['', '', '', ''], + dtype='|S1'), + 'depID': 23, + 'fileName': 0, + 'formula': 103408364, + 'fsValid': 0, + 'hsA': 1.0, + 'hsB': 0.0, + 'kindBits': '\x00', + 'modDate': 3001672861, + 'next': 0, + 'npnts': 10, + 'srcFldr': 0, + 'swModified': 1, + 'topFullScale': 0.0, + 'type': 2, + 'useBits': '\x00', + 'wModified': 1, + 'wUnused': array(['', ''], + dtype='|S1'), + 'waveNoteH': 0, + 'whVersion': 0, + 'xUnits': array(['', '', '', ''], + dtype='|S1')}}} >>> dumpibw('mac-version5.ibw') # doctest: +REPORT_UDIFF -array([ 5., 4., 3., 2., 1.], dtype=float32) -{'checksum': -12033, - 'dataEUnits': '', - 'dataEUnitsSize': 0, - 'dimEUnits': ['', '', '', ''], - 'dimEUnitsSize': array([0, 0, 0, 0]), - 'dimLabels': [['Column0'], [], [], []], - 'dimLabelsSize': array([64, 0, 0, 0]), - 'formula': '', - 'formulaSize': 0, - 'note': 'This is a test.', - 'noteSize': 15, - 'optionsSize1': 0, - 'optionsSize2': 0, - 'sIndicesSize': 0, - 'version': 5, - 'wfmSize': 340} -{'aModified': 0, - 'bname': array(['v', 'e', 'r', 's', 'i', 'o', 'n', '5', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''], - dtype='|S1'), - 'botFullScale': 0.0, - 'creationDate': 3001252180, - 'dFolder': 69554896, - 'dLock': 0, - 'dataEUnits': 0, - 'dataUnits': array(['', '', '', ''], - dtype='|S1'), - 'depID': 27, - 'dimEUnits': array([0, 0, 0, 0]), - 'dimLabels': array([69554136, 0, 0, 0]), - 'dimUnits': array([['', '', '', ''], +{'version': 5, + 'wave': {'bin_header': {'checksum': -12033, + 'dataEUnitsSize': 0, + 'dimEUnitsSize': array([0, 0, 0, 0]), + 'dimLabelsSize': array([64, 0, 0, 0]), + 'formulaSize': 0, + 'noteSize': 15, + 'optionsSize1': 0, + 'optionsSize2': 0, + 'sIndicesSize': 0, + 'wfmSize': 340}, + 'data_units': '', + 'dimension_units': '', + 'formula': '', + 'labels': [['Column0'], [], [], []], + 'note': 'This is a test.', + 'sIndices': array([], dtype=float64), + 'wData': array([ 5., 4., 3., 2., 1.], dtype=float32), + 'wave_header': {'aModified': 0, + 'bname': 'version5', + 'botFullScale': 0.0, + 'creationDate': 3001252180, + 'dFolder': 69554896, + 'dLock': 0, + 'dataEUnits': 0, + 'dataUnits': array(['', '', '', ''], + dtype='|S1'), + 'depID': 27, + 'dimEUnits': array([0, 0, 0, 0]), + 'dimLabels': array([69554136, 0, 0, 0]), + 'dimUnits': array([['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']], dtype='|S1'), - 'fileName': 69554292, - 'formula': 0, - 'fsValid': 0, - 'kindBits': '\x00', - 'modDate': 3001573601, - 'nDim': array([5, 0, 0, 0]), - 'next': 69555212, - 'npnts': 5, - 'sIndices': 0, - 'sfA': array([ 1., 1., 1., 1.]), - 'sfB': array([ 0., 0., 0., 0.]), - 'srcFldr': -32349, - 'swModified': 1, - 'topFullScale': 0.0, - 'type': 2, - 'useBits': '\x00', - 'wData': 5.0, - 'wModified': 0, - 'waveNoteH': 69554032, - 'whUnused': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - 'whVersion': 1, - 'whpad1': array(['', '', '', '', '', ''], - dtype='|S1'), - 'whpad2': 0, - 'whpad3': 0, - 'whpad4': 0} + 'fileName': 69554292, + 'formula': 0, + 'fsValid': 0, + 'kindBits': '\x00', + 'modDate': 3001573601, + 'nDim': array([5, 0, 0, 0]), + 'next': 69555212, + 'npnts': 5, + 'sIndices': 0, + 'sfA': array([ 1., 1., 1., 1.]), + 'sfB': array([ 0., 0., 0., 0.]), + 'srcFldr': -32349, + 'swModified': 1, + 'topFullScale': 0.0, + 'type': 2, + 'useBits': '\x00', + 'wModified': 0, + 'waveNoteH': 69554032, + 'whUnused': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + 'whVersion': 1, + 'whpad1': array(['', '', '', '', '', ''], + dtype='|S1'), + 'whpad2': 0, + 'whpad3': 0, + 'whpad4': 0}}} >>> dumpibw('mac-zeroPointWave.ibw') # doctest: +REPORT_UDIFF -array([], dtype=float32) -{'checksum': -15649, - 'dataEUnits': '', - 'dataEUnitsSize': 0, - 'dimEUnits': ['', '', '', ''], - 'dimEUnitsSize': array([0, 0, 0, 0]), - 'dimLabels': [[], [], [], []], - 'dimLabelsSize': array([0, 0, 0, 0]), - 'formula': '', - 'formulaSize': 0, - 'note': '', - 'noteSize': 0, - 'optionsSize1': 0, - 'optionsSize2': 0, - 'sIndicesSize': 0, - 'version': 5, - 'wfmSize': 320} -{'aModified': 3, - 'bname': array(['z', 'e', 'r', 'o', 'W', 'a', 'v', 'e', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''], - dtype='|S1'), - 'botFullScale': 0.0, - 'creationDate': 3001573964, - 'dFolder': 69554896, - 'dLock': 0, - 'dataEUnits': 0, - 'dataUnits': array(['', '', '', ''], - dtype='|S1'), - 'depID': 29, - 'dimEUnits': array([0, 0, 0, 0]), - 'dimLabels': array([0, 0, 0, 0]), - 'dimUnits': array([['', '', '', ''], +{'version': 5, + 'wave': {'bin_header': {'checksum': -15649, + 'dataEUnitsSize': 0, + 'dimEUnitsSize': array([0, 0, 0, 0]), + 'dimLabelsSize': array([0, 0, 0, 0]), + 'formulaSize': 0, + 'noteSize': 0, + 'optionsSize1': 0, + 'optionsSize2': 0, + 'sIndicesSize': 0, + 'wfmSize': 320}, + 'data_units': '', + 'dimension_units': '', + 'formula': '', + 'labels': [[], [], [], []], + 'note': '', + 'sIndices': array([], dtype=float64), + 'wData': array([], dtype=float32), + 'wave_header': {'aModified': 3, + 'bname': 'zeroWave', + 'botFullScale': 0.0, + 'creationDate': 3001573964, + 'dFolder': 69554896, + 'dLock': 0, + 'dataEUnits': 0, + 'dataUnits': array(['', '', '', ''], + dtype='|S1'), + 'depID': 29, + 'dimEUnits': array([0, 0, 0, 0]), + 'dimLabels': array([0, 0, 0, 0]), + 'dimUnits': array([['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']], dtype='|S1'), - 'fileName': 0, - 'formula': 0, - 'fsValid': 0, - 'kindBits': '\x00', - 'modDate': 3001573964, - 'nDim': array([0, 0, 0, 0]), - 'next': 0, - 'npnts': 0, - 'sIndices': 0, - 'sfA': array([ 1., 1., 1., 1.]), - 'sfB': array([ 0., 0., 0., 0.]), - 'srcFldr': 0, - 'swModified': 1, - 'topFullScale': 0.0, - 'type': 2, - 'useBits': '\x00', - 'wData': 0.0, - 'wModified': 1, - 'waveNoteH': 0, - 'whUnused': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - 'whVersion': 1, - 'whpad1': array(['', '', '', '', '', ''], - dtype='|S1'), - 'whpad2': 0, - 'whpad3': 0, - 'whpad4': 0} + 'fileName': 0, + 'formula': 0, + 'fsValid': 0, + 'kindBits': '\x00', + 'modDate': 3001573964, + 'nDim': array([0, 0, 0, 0]), + 'next': 0, + 'npnts': 0, + 'sIndices': 0, + 'sfA': array([ 1., 1., 1., 1.]), + 'sfB': array([ 0., 0., 0., 0.]), + 'srcFldr': 0, + 'swModified': 1, + 'topFullScale': 0.0, + 'type': 2, + 'useBits': '\x00', + 'wModified': 1, + 'waveNoteH': 0, + 'whUnused': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + 'whVersion': 1, + 'whpad1': array(['', '', '', '', '', ''], + dtype='|S1'), + 'whpad2': 0, + 'whpad3': 0, + 'whpad4': 0}}} >>> dumpibw('win-double.ibw') # doctest: +REPORT_UDIFF -array([ 5., 4., 3., 2., 1.]) -{'checksum': 28962, - 'note': '', - 'noteSize': 0, - 'pictSize': 0, - 'version': 2, - 'wfmSize': 166} -{'aModified': 0, - 'bname': array(['d', 'o', 'u', 'b', 'l', 'e', '', '', '', '', '', '', '', '', '', - '', '', '', '', ''], - dtype='|S1'), - 'botFullScale': 0.0, - 'creationDate': 3001587842, - 'dataUnits': array(['', '', '', ''], - dtype='|S1'), - 'depID': 0, - 'fileName': 0, - 'formula': 0, - 'fsValid': 0, - 'hsA': 1.0, - 'hsB': 0.0, - 'kindBits': '\x00', - 'modDate': 3001587842, - 'next': 0, - 'npnts': 5, - 'srcFldr': 0, - 'swModified': 0, - 'topFullScale': 0.0, - 'type': 4, - 'useBits': '\x00', - 'wData': array([ 0. , 2.3125, 0. , 2.25 ]), - 'wModified': 0, - 'wUnused': array(['', ''], - dtype='|S1'), - 'waveNoteH': 0, - 'whVersion': 0, - 'xUnits': array(['', '', '', ''], - dtype='|S1')} +{'version': 2, + 'wave': {'bin_header': {'checksum': 28962, + 'noteSize': 0, + 'pictSize': 0, + 'wfmSize': 166}, + 'note': '', + 'padding': array([], dtype=float64), + 'wData': array([ 5., 4., 3., 2., 1.]), + 'wave_header': {'aModified': 0, + 'bname': 'double', + 'botFullScale': 0.0, + 'creationDate': 3001587842, + 'dataUnits': array(['', '', '', ''], + dtype='|S1'), + 'depID': 0, + 'fileName': 0, + 'formula': 0, + 'fsValid': 0, + 'hsA': 1.0, + 'hsB': 0.0, + 'kindBits': '\x00', + 'modDate': 3001587842, + 'next': 0, + 'npnts': 5, + 'srcFldr': 0, + 'swModified': 0, + 'topFullScale': 0.0, + 'type': 4, + 'useBits': '\x00', + 'wModified': 0, + 'wUnused': array(['', ''], + dtype='|S1'), + 'waveNoteH': 0, + 'whVersion': 0, + 'xUnits': array(['', '', '', ''], + dtype='|S1')}}} >>> dumpibw('win-textWave.ibw') # doctest: +REPORT_UDIFF -array(['Mary', 'had', 'a', 'little', 'lamb'], - dtype='|S6') -{'checksum': 184, - 'dataEUnits': '', - 'dataEUnitsSize': 0, - 'dimEUnits': ['', '', '', ''], - 'dimEUnitsSize': array([0, 0, 0, 0]), - 'dimLabels': [[], [], [], []], - 'dimLabelsSize': array([0, 0, 0, 0]), - 'formula': '', - 'formulaSize': 0, - 'note': '', - 'noteSize': 0, - 'optionsSize1': 0, - 'optionsSize2': 0, - 'sIndices': array([ 4, 7, 8, 14, 18], dtype=uint32), - 'sIndicesSize': 20, - 'version': 5, - 'wfmSize': 338} -{'aModified': 0, - 'bname': array(['t', 'e', 'x', 't', '0', '', '', '', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''], - dtype='|S1'), - 'botFullScale': 0.0, - 'creationDate': 3001571199, - 'dFolder': 8108612, - 'dLock': 0, - 'dataEUnits': 0, - 'dataUnits': array(['', '', '', ''], - dtype='|S1'), - 'depID': 32, - 'dimEUnits': array([0, 0, 0, 0]), - 'dimLabels': array([0, 0, 0, 0]), - 'dimUnits': array([['', '', '', ''], +{'version': 5, + 'wave': {'bin_header': {'checksum': 184, + 'dataEUnitsSize': 0, + 'dimEUnitsSize': array([0, 0, 0, 0]), + 'dimLabelsSize': array([0, 0, 0, 0]), + 'formulaSize': 0, + 'noteSize': 0, + 'optionsSize1': 0, + 'optionsSize2': 0, + 'sIndicesSize': 20, + 'wfmSize': 338}, + 'data_units': '', + 'dimension_units': '', + 'formula': '', + 'labels': [[], [], [], []], + 'note': '', + 'sIndices': array([ 4, 7, 8, 14, 18]), + 'wData': array(['Mary', 'had', 'a', 'little', 'lamb'], + dtype='|S6'), + 'wave_header': {'aModified': 0, + 'bname': 'text0', + 'botFullScale': 0.0, + 'creationDate': 3001571199, + 'dFolder': 8108612, + 'dLock': 0, + 'dataEUnits': 0, + 'dataUnits': array(['', '', '', ''], + dtype='|S1'), + 'depID': 32, + 'dimEUnits': array([0, 0, 0, 0]), + 'dimLabels': array([0, 0, 0, 0]), + 'dimUnits': array([['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']], dtype='|S1'), - 'fileName': 7814472, - 'formula': 0, - 'fsValid': 0, - 'kindBits': '\x00', - 'modDate': 3001571215, - 'nDim': array([5, 0, 0, 0]), - 'next': 0, - 'npnts': 5, - 'sIndices': 8133100, - 'sfA': array([ 1., 1., 1., 1.]), - 'sfB': array([ 0., 0., 0., 0.]), - 'srcFldr': -1007, - 'swModified': 0, - 'topFullScale': 0.0, - 'type': 0, - 'useBits': '\x00', - 'wData': 7.865683337909351e+34, - 'wModified': 1, - 'waveNoteH': 0, - 'whUnused': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - 'whVersion': 1, - 'whpad1': array(['', '', '', '', '', ''], - dtype='|S1'), - 'whpad2': 0, - 'whpad3': 0, - 'whpad4': 0} + 'fileName': 7814472, + 'formula': 0, + 'fsValid': 0, + 'kindBits': '\x00', + 'modDate': 3001571215, + 'nDim': array([5, 0, 0, 0]), + 'next': 0, + 'npnts': 5, + 'sIndices': 8133100, + 'sfA': array([ 1., 1., 1., 1.]), + 'sfB': array([ 0., 0., 0., 0.]), + 'srcFldr': -1007, + 'swModified': 0, + 'topFullScale': 0.0, + 'type': 0, + 'useBits': '\x00', + 'wModified': 1, + 'waveNoteH': 0, + 'whUnused': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + 'whVersion': 1, + 'whpad1': array(['', '', '', '', '', ''], + dtype='|S1'), + 'whpad2': 0, + 'whpad3': 0, + 'whpad4': 0}}} >>> dumpibw('win-version2.ibw') # doctest: +REPORT_UDIFF -array([ 5., 4., 3., 2., 1.], dtype=float32) -{'checksum': 1047, - 'note': 'This is a test.', - 'noteSize': 15, - 'pictSize': 0, - 'version': 2, - 'wfmSize': 146} -{'aModified': 0, - 'bname': array(['v', 'e', 'r', 's', 'i', 'o', 'n', '2', '', '', '', '', '', '', '', - '', '', '', '', ''], - dtype='|S1'), - 'botFullScale': 0.0, - 'creationDate': 3001251979, - 'dataUnits': array(['', '', '', ''], - dtype='|S1'), - 'depID': 0, - 'fileName': 0, - 'formula': 0, - 'fsValid': 0, - 'hsA': 1.0, - 'hsB': 0.0, - 'kindBits': '\x00', - 'modDate': 3001573594, - 'next': 0, - 'npnts': 5, - 'srcFldr': 0, - 'swModified': 0, - 'topFullScale': 0.0, - 'type': 2, - 'useBits': '\x00', - 'wData': array([ 5., 4., 3., 2.]), - 'wModified': 0, - 'wUnused': array(['', ''], - dtype='|S1'), - 'waveNoteH': 0, - 'whVersion': 0, - 'xUnits': array(['', '', '', ''], - dtype='|S1')} +{'version': 2, + 'wave': {'bin_header': {'checksum': 1047, + 'noteSize': 15, + 'pictSize': 0, + 'wfmSize': 146}, + 'note': 'This is a test.', + 'padding': array([], dtype=float64), + 'wData': array([ 5., 4., 3., 2., 1.], dtype=float32), + 'wave_header': {'aModified': 0, + 'bname': 'version2', + 'botFullScale': 0.0, + 'creationDate': 3001251979, + 'dataUnits': array(['', '', '', ''], + dtype='|S1'), + 'depID': 0, + 'fileName': 0, + 'formula': 0, + 'fsValid': 0, + 'hsA': 1.0, + 'hsB': 0.0, + 'kindBits': '\x00', + 'modDate': 3001573594, + 'next': 0, + 'npnts': 5, + 'srcFldr': 0, + 'swModified': 0, + 'topFullScale': 0.0, + 'type': 2, + 'useBits': '\x00', + 'wModified': 0, + 'wUnused': array(['', ''], + dtype='|S1'), + 'waveNoteH': 0, + 'whVersion': 0, + 'xUnits': array(['', '', '', ''], + dtype='|S1')}}} >>> dumpibw('win-version5.ibw') # doctest: +REPORT_UDIFF -array([ 5., 4., 3., 2., 1.], dtype=float32) -{'checksum': 13214, - 'dataEUnits': '', - 'dataEUnitsSize': 0, - 'dimEUnits': ['', '', '', ''], - 'dimEUnitsSize': array([0, 0, 0, 0]), - 'dimLabels': [['Column0'], [], [], []], - 'dimLabelsSize': array([64, 0, 0, 0]), - 'formula': '', - 'formulaSize': 0, - 'note': 'This is a test.', - 'noteSize': 15, - 'optionsSize1': 0, - 'optionsSize2': 0, - 'sIndicesSize': 0, - 'version': 5, - 'wfmSize': 340} -{'aModified': 0, - 'bname': array(['v', 'e', 'r', 's', 'i', 'o', 'n', '5', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''], - dtype='|S1'), - 'botFullScale': 0.0, - 'creationDate': 3001252180, - 'dFolder': 8108612, - 'dLock': 0, - 'dataEUnits': 0, - 'dataUnits': array(['', '', '', ''], - dtype='|S1'), - 'depID': 30, - 'dimEUnits': array([0, 0, 0, 0]), - 'dimLabels': array([8138784, 0, 0, 0]), - 'dimUnits': array([['', '', '', ''], +{'version': 5, + 'wave': {'bin_header': {'checksum': 13214, + 'dataEUnitsSize': 0, + 'dimEUnitsSize': array([0, 0, 0, 0]), + 'dimLabelsSize': array([64, 0, 0, 0]), + 'formulaSize': 0, + 'noteSize': 15, + 'optionsSize1': 0, + 'optionsSize2': 0, + 'sIndicesSize': 0, + 'wfmSize': 340}, + 'data_units': '', + 'dimension_units': '', + 'formula': '', + 'labels': [['Column0'], [], [], []], + 'note': 'This is a test.', + 'sIndices': array([], dtype=float64), + 'wData': array([ 5., 4., 3., 2., 1.], dtype=float32), + 'wave_header': {'aModified': 0, + 'bname': 'version5', + 'botFullScale': 0.0, + 'creationDate': 3001252180, + 'dFolder': 8108612, + 'dLock': 0, + 'dataEUnits': 0, + 'dataUnits': array(['', '', '', ''], + dtype='|S1'), + 'depID': 30, + 'dimEUnits': array([0, 0, 0, 0]), + 'dimLabels': array([8138784, 0, 0, 0]), + 'dimUnits': array([['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']], dtype='|S1'), - 'fileName': 8131824, - 'formula': 0, - 'fsValid': 0, - 'kindBits': '\x00', - 'modDate': 3001573601, - 'nDim': array([5, 0, 0, 0]), - 'next': 8125236, - 'npnts': 5, - 'sIndices': 0, - 'sfA': array([ 1., 1., 1., 1.]), - 'sfB': array([ 0., 0., 0., 0.]), - 'srcFldr': -1007, - 'swModified': 0, - 'topFullScale': 0.0, - 'type': 2, - 'useBits': '\x00', - 'wData': 5.0, - 'wModified': 1, - 'waveNoteH': 8131596, - 'whUnused': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - 'whVersion': 1, - 'whpad1': array(['', '', '', '', '', ''], - dtype='|S1'), - 'whpad2': 0, - 'whpad3': 0, - 'whpad4': 0} + 'fileName': 8131824, + 'formula': 0, + 'fsValid': 0, + 'kindBits': '\x00', + 'modDate': 3001573601, + 'nDim': array([5, 0, 0, 0]), + 'next': 8125236, + 'npnts': 5, + 'sIndices': 0, + 'sfA': array([ 1., 1., 1., 1.]), + 'sfB': array([ 0., 0., 0., 0.]), + 'srcFldr': -1007, + 'swModified': 0, + 'topFullScale': 0.0, + 'type': 2, + 'useBits': '\x00', + 'wModified': 1, + 'waveNoteH': 8131596, + 'whUnused': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + 'whVersion': 1, + 'whpad1': array(['', '', '', '', '', ''], + dtype='|S1'), + 'whpad2': 0, + 'whpad3': 0, + 'whpad4': 0}}} >>> dumpibw('win-zeroPointWave.ibw') # doctest: +REPORT_UDIFF -array([], dtype=float32) -{'checksum': 27541, - 'dataEUnits': '', - 'dataEUnitsSize': 0, - 'dimEUnits': ['', '', '', ''], - 'dimEUnitsSize': array([0, 0, 0, 0]), - 'dimLabels': [[], [], [], []], - 'dimLabelsSize': array([0, 0, 0, 0]), - 'formula': '', - 'formulaSize': 0, - 'note': '', - 'noteSize': 0, - 'optionsSize1': 0, - 'optionsSize2': 0, - 'sIndicesSize': 0, - 'version': 5, - 'wfmSize': 320} -{'aModified': 3, - 'bname': array(['z', 'e', 'r', 'o', 'W', 'a', 'v', 'e', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''], - dtype='|S1'), - 'botFullScale': 0.0, - 'creationDate': 3001573964, - 'dFolder': 8108612, - 'dLock': 0, - 'dataEUnits': 0, - 'dataUnits': array(['', '', '', ''], - dtype='|S1'), - 'depID': 31, - 'dimEUnits': array([0, 0, 0, 0]), - 'dimLabels': array([0, 0, 0, 0]), - 'dimUnits': array([['', '', '', ''], +{'version': 5, + 'wave': {'bin_header': {'checksum': 27541, + 'dataEUnitsSize': 0, + 'dimEUnitsSize': array([0, 0, 0, 0]), + 'dimLabelsSize': array([0, 0, 0, 0]), + 'formulaSize': 0, + 'noteSize': 0, + 'optionsSize1': 0, + 'optionsSize2': 0, + 'sIndicesSize': 0, + 'wfmSize': 320}, + 'data_units': '', + 'dimension_units': '', + 'formula': '', + 'labels': [[], [], [], []], + 'note': '', + 'sIndices': array([], dtype=float64), + 'wData': array([], dtype=float32), + 'wave_header': {'aModified': 3, + 'bname': 'zeroWave', + 'botFullScale': 0.0, + 'creationDate': 3001573964, + 'dFolder': 8108612, + 'dLock': 0, + 'dataEUnits': 0, + 'dataUnits': array(['', '', '', ''], + dtype='|S1'), + 'depID': 31, + 'dimEUnits': array([0, 0, 0, 0]), + 'dimLabels': array([0, 0, 0, 0]), + 'dimUnits': array([['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']], dtype='|S1'), - 'fileName': 8125252, - 'formula': 0, - 'fsValid': 0, - 'kindBits': '\x00', - 'modDate': 3001573964, - 'nDim': array([0, 0, 0, 0]), - 'next': 8133140, - 'npnts': 0, - 'sIndices': 0, - 'sfA': array([ 1., 1., 1., 1.]), - 'sfB': array([ 0., 0., 0., 0.]), - 'srcFldr': -1007, - 'swModified': 0, - 'topFullScale': 0.0, - 'type': 2, - 'useBits': '\x00', - 'wData': 0.0, - 'wModified': 1, - 'waveNoteH': 0, - 'whUnused': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - 'whVersion': 1, - 'whpad1': array(['', '', '', '', '', ''], - dtype='|S1'), - 'whpad2': 0, - 'whpad3': 0, - 'whpad4': 0} + 'fileName': 8125252, + 'formula': 0, + 'fsValid': 0, + 'kindBits': '\x00', + 'modDate': 3001573964, + 'nDim': array([0, 0, 0, 0]), + 'next': 8133140, + 'npnts': 0, + 'sIndices': 0, + 'sfA': array([ 1., 1., 1., 1.]), + 'sfB': array([ 0., 0., 0., 0.]), + 'srcFldr': -1007, + 'swModified': 0, + 'topFullScale': 0.0, + 'type': 2, + 'useBits': '\x00', + 'wModified': 1, + 'waveNoteH': 0, + 'whUnused': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + 'whVersion': 1, + 'whpad1': array(['', '', '', '', '', ''], + dtype='|S1'), + 'whpad2': 0, + 'whpad3': 0, + 'whpad4': 0}}} >>> dumppxp('polar-graphs-demo.pxp') # doctest: +REPORT_UDIFF, +ELLIPSIS record 0: @@ -654,19 +630,44 @@ record 28: record 29: record 30: -{'header': {'numSysVars': 21, - 'numUserStrs': 0, - 'numUserVars': 0, - 'version': 1}, - 'sysVars': array([ 0., 0., 0., 0., 0., 0., 0., 0., 0., - 0., 0., 0., 0., 0., 0., 0., 0., 0., - 0., 0., 128.]), - 'userStrs': {}, - 'userVars': {}} +{'variables': {'sysVars': {'K0': 0.0, + 'K1': 0.0, + 'K10': 0.0, + 'K11': 0.0, + 'K12': 0.0, + 'K13': 0.0, + 'K14': 0.0, + 'K15': 0.0, + 'K16': 0.0, + 'K17': 0.0, + 'K18': 0.0, + 'K19': 0.0, + 'K2': 0.0, + 'K20': 128.0, + 'K3': 0.0, + 'K4': 0.0, + 'K5': 0.0, + 'K6': 0.0, + 'K7': 0.0, + 'K8': 0.0, + 'K9': 0.0}, + 'userStrs': {}, + 'userVars': {}, + 'var_header': {'numSysVars': 21, + 'numUserStrs': 0, + 'numUserVars': 0}}, + 'version': 1} record 31: '\x95 Polar Graphs Demo, v3.01\n\n' record 32: -array([ 0.30000001, 0.5448544 , 0.77480197, 0.97584349, 1.13573945, +{'version': 2, + 'wave': {'bin_header': {'checksum': -25004, + 'noteSize': 0, + 'pictSize': 0, + 'wfmSize': 638}, + 'note': '', + 'padding': array([], dtype=float64), + 'wData': array([ 0.30000001, 0.5448544 , 0.77480197, 0.97584349, 1.13573945, 1.24475539, 1.2962544 , 1.28710103, 1.21785283, 1.09272552, 0.91933674, 0.7082426 , 0.47229454, 0.22585714, -0.01606643, -0.23874778, -0.42862982, -0.57415301, -0.6664573 , -0.69992352, @@ -691,46 +692,44 @@ array([ 0.30000001, 0.5448544 , 0.77480197, 0.97584349, 1.13573945, 1.17415261, 1.0286293 , 0.83874667, 0.61606491, 0.37414294, 0.12770344, -0.1082412 , -0.31933719, -0.49272597, -0.61785328, -0.6871013 , -0.69625437, -0.64475471, -0.53574032, -0.37584305, - -0.17479956, 0.05514668, 0.30000135], dtype=float32) -{'checksum': -25004, - 'note': '', - 'noteSize': 0, - 'pictSize': 0, - 'version': 2, - 'wfmSize': 638} -{'aModified': 0, - 'bname': array(['r', 'a', 'd', 'i', 'u', 's', 'D', 'a', 't', 'a', '', '', '', '', - '', '', '', '', '', ''], - dtype='|S1'), - 'botFullScale': 0.0, - 'creationDate': 0, - 'dataUnits': array(['', '', '', ''], - dtype='|S1'), - 'depID': 0, - 'fileName': 0, - 'formula': 0, - 'fsValid': 0, - 'hsA': 0.04908738521234052, - 'hsB': 0.0, - 'kindBits': '\x00', - 'modDate': 2845545774, - 'next': 0, - 'npnts': 128, - 'srcFldr': 0, - 'swModified': 0, - 'topFullScale': 0.0, - 'type': 2, - 'useBits': '\x00', - 'wData': array([ 0.30000001, 0.5448544 , 0.77480197, 0.97584349]), - 'wModified': 0, - 'wUnused': array(['', ''], - dtype='|S1'), - 'waveNoteH': 0, - 'whVersion': 0, - 'xUnits': array(['', '', '', ''], - dtype='|S1')} + -0.17479956, 0.05514668, 0.30000135], dtype=float32), + 'wave_header': {'aModified': 0, + 'bname': 'radiusData', + 'botFullScale': 0.0, + 'creationDate': 0, + 'dataUnits': array(['', '', '', ''], + dtype='|S1'), + 'depID': 0, + 'fileName': 0, + 'formula': 0, + 'fsValid': 0, + 'hsA': 0.04908738521234052, + 'hsB': 0.0, + 'kindBits': '\x00', + 'modDate': 2845545774, + 'next': 0, + 'npnts': 128, + 'srcFldr': 0, + 'swModified': 0, + 'topFullScale': 0.0, + 'type': 2, + 'useBits': '\x00', + 'wModified': 0, + 'wUnused': array(['', ''], + dtype='|S1'), + 'waveNoteH': 0, + 'whVersion': 0, + 'xUnits': array(['', '', '', ''], + dtype='|S1')}}} record 33: -array([ 0. , 0.0494739 , 0.0989478 , 0.1484217 , 0.1978956 , +{'version': 2, + 'wave': {'bin_header': {'checksum': 28621, + 'noteSize': 0, + 'pictSize': 0, + 'wfmSize': 638}, + 'note': '', + 'padding': array([], dtype=float64), + 'wData': array([ 0. , 0.0494739 , 0.0989478 , 0.1484217 , 0.1978956 , 0.24736951, 0.29684341, 0.34631732, 0.3957912 , 0.44526511, 0.49473903, 0.54421294, 0.59368682, 0.6431607 , 0.69263464, 0.74210852, 0.79158241, 0.84105635, 0.89053023, 0.94000411, @@ -755,46 +754,54 @@ array([ 0. , 0.0494739 , 0.0989478 , 0.1484217 , 0.1978956 , 5.44212914, 5.4916029 , 5.54107714, 5.5905509 , 5.64002466, 5.6894989 , 5.73897219, 5.78844643, 5.83792019, 5.88739443, 5.93686819, 5.98634195, 6.03581619, 6.08528948, 6.13476372, - 6.18423796, 6.23371172, 6.28318548], dtype=float32) -{'checksum': 28621, - 'note': '', - 'noteSize': 0, - 'pictSize': 0, - 'version': 2, - 'wfmSize': 638} -{'aModified': 0, - 'bname': array(['a', 'n', 'g', 'l', 'e', 'D', 'a', 't', 'a', '', '', '', '', '', '', - '', '', '', '', ''], - dtype='|S1'), - 'botFullScale': 0.0, - 'creationDate': 0, - 'dataUnits': array(['', '', '', ''], - dtype='|S1'), - 'depID': 0, - 'fileName': 0, - 'formula': 0, - 'fsValid': 0, - 'hsA': 0.04908738521234052, - 'hsB': 0.0, - 'kindBits': '\x00', - 'modDate': 2845470039, - 'next': 0, - 'npnts': 128, - 'srcFldr': 0, - 'swModified': 0, - 'topFullScale': 0.0, - 'type': 2, - 'useBits': '\x00', - 'wData': array([ 0. , 0.0494739, 0.0989478, 0.1484217]), - 'wModified': 0, - 'wUnused': array(['', ''], - dtype='|S1'), - 'waveNoteH': 0, - 'whVersion': 0, - 'xUnits': array(['', '', '', ''], - dtype='|S1')} + 6.18423796, 6.23371172, 6.28318548], dtype=float32), + 'wave_header': {'aModified': 0, + 'bname': 'angleData', + 'botFullScale': 0.0, + 'creationDate': 0, + 'dataUnits': array(['', '', '', ''], + dtype='|S1'), + 'depID': 0, + 'fileName': 0, + 'formula': 0, + 'fsValid': 0, + 'hsA': 0.04908738521234052, + 'hsB': 0.0, + 'kindBits': '\x00', + 'modDate': 2845470039, + 'next': 0, + 'npnts': 128, + 'srcFldr': 0, + 'swModified': 0, + 'topFullScale': 0.0, + 'type': 2, + 'useBits': '\x00', + 'wModified': 0, + 'wUnused': array(['', ''], + dtype='|S1'), + 'waveNoteH': 0, + 'whVersion': 0, + 'xUnits': array(['', '', '', ''], + dtype='|S1')}}} record 34: -array([ 1.83690956e-17, 2.69450769e-02, 7.65399113e-02, +{'version': 5, + 'wave': {'bin_header': {'checksum': 23021, + 'dataEUnitsSize': 0, + 'dimEUnitsSize': array([0, 0, 0, 0]), + 'dimLabelsSize': array([0, 0, 0, 0]), + 'formulaSize': 80, + 'noteSize': 0, + 'optionsSize1': 0, + 'optionsSize2': 0, + 'sIndicesSize': 0, + 'wfmSize': 832}, + 'data_units': '', + 'dimension_units': '', + 'formula': ' PolarRadiusFunction(radiusData,1,0) * cos(PolarAngleFunction(angleData,3,1,2))', + 'labels': [[], [], [], []], + 'note': '', + 'sIndices': array([], dtype=float64), + 'wData': array([ 1.83690956e-17, 2.69450769e-02, 7.65399113e-02, 1.44305170e-01, 2.23293692e-01, 3.04783821e-01, 3.79158467e-01, 4.36888516e-01, 4.69528973e-01, 4.70633775e-01, 4.36502904e-01, 3.66688997e-01, @@ -836,70 +843,68 @@ array([ 1.83690956e-17, 2.69450769e-02, 7.65399113e-02, 1.51621893e-01, 2.12215677e-01, 2.38205954e-01, 2.33226836e-01, 2.03656554e-01, 1.57870770e-01, 1.05330117e-01, 5.55786416e-02, 1.72677450e-02, - -2.72719120e-03, 5.24539061e-08], dtype=float32) -{'checksum': 23021, - 'dataEUnits': '', - 'dataEUnitsSize': 0, - 'dimEUnits': ['', '', '', ''], - 'dimEUnitsSize': array([0, 0, 0, 0]), - 'dimLabels': [[], [], [], []], - 'dimLabelsSize': array([0, 0, 0, 0]), - 'formula': 'PolarRadiusFunction(radiusData,1,0) * cos(PolarAngleFunction(angleData,3,1,2))\x00', - 'formulaSize': 80, - 'note': '', - 'noteSize': 0, - 'optionsSize1': 0, - 'optionsSize2': 0, - 'sIndicesSize': 0, - 'version': 5, - 'wfmSize': 832} -{'aModified': 0, - 'bname': array(['W', '_', 'p', 'l', 'r', 'X', '5', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''], - dtype='|S1'), - 'botFullScale': 0.0, - 'creationDate': 0, - 'dFolder': 7848580, - 'dLock': 0, - 'dataEUnits': 0, - 'dataUnits': array(['', '', '', ''], - dtype='|S1'), - 'depID': 24, - 'dimEUnits': array([0, 0, 0, 0]), - 'dimLabels': array([0, 0, 0, 0]), - 'dimUnits': array([['', '', '', ''], + -2.72719120e-03, 5.24539061e-08], dtype=float32), + 'wave_header': {'aModified': 0, + 'bname': 'W_plrX5', + 'botFullScale': 0.0, + 'creationDate': 0, + 'dFolder': 7848580, + 'dLock': 0, + 'dataEUnits': 0, + 'dataUnits': array(['', '', '', ''], + dtype='|S1'), + 'depID': 24, + 'dimEUnits': array([0, 0, 0, 0]), + 'dimLabels': array([0, 0, 0, 0]), + 'dimUnits': array([['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']], dtype='|S1'), - 'fileName': 0, - 'formula': 8054500, - 'fsValid': 0, - 'kindBits': '\x00', - 'modDate': 2985072242, - 'nDim': array([128, 0, 0, 0]), - 'next': 8054516, - 'npnts': 128, - 'sIndices': 0, - 'sfA': array([ 0.04908739, 1. , 1. , 1. ]), - 'sfB': array([ 0., 0., 0., 0.]), - 'srcFldr': 0, - 'swModified': 0, - 'topFullScale': 0.0, - 'type': 2, - 'useBits': '\x00', - 'wData': 1.8369095638207904e-17, - 'wModified': 0, - 'waveNoteH': 0, - 'whUnused': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - 'whVersion': 1, - 'whpad1': array(['', '', '', '', '', ''], - dtype='|S1'), - 'whpad2': 0, - 'whpad3': 0, - 'whpad4': 0} + 'fileName': 0, + 'formula': 8054500, + 'fsValid': 0, + 'kindBits': '\x00', + 'modDate': 2985072242, + 'nDim': array([128, 0, 0, 0]), + 'next': 8054516, + 'npnts': 128, + 'sIndices': 0, + 'sfA': array([ 0.04908739, 1. , 1. , 1. ]), + 'sfB': array([ 0., 0., 0., 0.]), + 'srcFldr': 0, + 'swModified': 0, + 'topFullScale': 0.0, + 'type': 2, + 'useBits': '\x00', + 'wModified': 0, + 'waveNoteH': 0, + 'whUnused': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + 'whVersion': 1, + 'whpad1': array(['', '', '', '', '', ''], + dtype='|S1'), + 'whpad2': 0, + 'whpad3': 0, + 'whpad4': 0}}} record 35: -array([ 0.30000001, 0.54418772, 0.77101213, 0.96511477, 1.1135726 , +{'version': 5, + 'wave': {'bin_header': {'checksum': -9146, + 'dataEUnitsSize': 0, + 'dimEUnitsSize': array([0, 0, 0, 0]), + 'dimLabelsSize': array([0, 0, 0, 0]), + 'formulaSize': 80, + 'noteSize': 82, + 'optionsSize1': 0, + 'optionsSize2': 0, + 'sIndicesSize': 0, + 'wfmSize': 832}, + 'data_units': '', + 'dimension_units': '', + 'formula': ' PolarRadiusFunction(radiusData,1,0) * sin(PolarAngleFunction(angleData,3,1,2))', + 'labels': [[], [], [], []], + 'note': 'shadowX=W_plrX5,appendRadius=radiusData,appendAngleData=angleData,angleDataUnits=2', + 'sIndices': array([], dtype=float64), + 'wData': array([ 0.30000001, 0.54418772, 0.77101213, 0.96511477, 1.1135726 , 1.20686483, 1.23956215, 1.21068466, 1.12370288, 0.98618096, 0.80910152, 0.60592639, 0.39147732, 0.18073183, -0.01236418, -0.17596789, -0.30120692, -0.38277394, -0.41920158, -0.41280419, @@ -924,70 +929,58 @@ array([ 0.30000001, 0.54418772, 0.77101213, 0.96511477, 1.1135726 , 0.78277934, 0.72283876, 0.6181944 , 0.47410288, 0.29939076, 0.10585135, -0.09260413, -0.28104633, -0.44468346, -0.57008827, -0.64630753, -0.66580337, -0.62512833, -0.52528399, -0.37171093, - -0.17394456, 0.0550792 , 0.30000135], dtype=float32) -{'checksum': -9146, - 'dataEUnits': '', - 'dataEUnitsSize': 0, - 'dimEUnits': ['', '', '', ''], - 'dimEUnitsSize': array([0, 0, 0, 0]), - 'dimLabels': [[], [], [], []], - 'dimLabelsSize': array([0, 0, 0, 0]), - 'formula': 'PolarRadiusFunction(radiusData,1,0) * sin(PolarAngleFunction(angleData,3,1,2))\x00', - 'formulaSize': 80, - 'note': 'shadowX=W_plrX5,appendRadius=radiusData,appendAngleData=angleData,angleDataUnits=2', - 'noteSize': 82, - 'optionsSize1': 0, - 'optionsSize2': 0, - 'sIndicesSize': 0, - 'version': 5, - 'wfmSize': 832} -{'aModified': 0, - 'bname': array(['W', '_', 'p', 'l', 'r', 'Y', '5', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''], - dtype='|S1'), - 'botFullScale': 0.0, - 'creationDate': 0, - 'dFolder': 7848580, - 'dLock': 0, - 'dataEUnits': 0, - 'dataUnits': array(['', '', '', ''], - dtype='|S1'), - 'depID': 26, - 'dimEUnits': array([0, 0, 0, 0]), - 'dimLabels': array([0, 0, 0, 0]), - 'dimUnits': array([['', '', '', ''], + -0.17394456, 0.0550792 , 0.30000135], dtype=float32), + 'wave_header': {'aModified': 0, + 'bname': 'W_plrY5', + 'botFullScale': 0.0, + 'creationDate': 0, + 'dFolder': 7848580, + 'dLock': 0, + 'dataEUnits': 0, + 'dataUnits': array(['', '', '', ''], + dtype='|S1'), + 'depID': 26, + 'dimEUnits': array([0, 0, 0, 0]), + 'dimLabels': array([0, 0, 0, 0]), + 'dimUnits': array([['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']], dtype='|S1'), - 'fileName': 0, - 'formula': 8054532, - 'fsValid': 0, - 'kindBits': '\x00', - 'modDate': 2985072242, - 'nDim': array([128, 0, 0, 0]), - 'next': 8084972, - 'npnts': 128, - 'sIndices': 0, - 'sfA': array([ 0.04908739, 1. , 1. , 1. ]), - 'sfB': array([ 0., 0., 0., 0.]), - 'srcFldr': 0, - 'swModified': 0, - 'topFullScale': 0.0, - 'type': 2, - 'useBits': '\x00', - 'wData': 0.30000001192092896, - 'wModified': 0, - 'waveNoteH': 7996608, - 'whUnused': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - 'whVersion': 1, - 'whpad1': array(['', '', '', '', '', ''], - dtype='|S1'), - 'whpad2': 0, - 'whpad3': 0, - 'whpad4': 0} + 'fileName': 0, + 'formula': 8054532, + 'fsValid': 0, + 'kindBits': '\x00', + 'modDate': 2985072242, + 'nDim': array([128, 0, 0, 0]), + 'next': 8084972, + 'npnts': 128, + 'sIndices': 0, + 'sfA': array([ 0.04908739, 1. , 1. , 1. ]), + 'sfB': array([ 0., 0., 0., 0.]), + 'srcFldr': 0, + 'swModified': 0, + 'topFullScale': 0.0, + 'type': 2, + 'useBits': '\x00', + 'wModified': 0, + 'waveNoteH': 7996608, + 'whUnused': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + 'whVersion': 1, + 'whpad1': array(['', '', '', '', '', ''], + dtype='|S1'), + 'whpad2': 0, + 'whpad3': 0, + 'whpad4': 0}}} record 36: -array([ 0.2617994 , 0.27842158, 0.29504377, 0.31166595, 0.32828814, +{'version': 2, + 'wave': {'bin_header': {'checksum': 14307, + 'noteSize': 0, + 'pictSize': 0, + 'wfmSize': 382}, + 'note': '', + 'padding': array([], dtype=float64), + 'wData': array([ 0.2617994 , 0.27842158, 0.29504377, 0.31166595, 0.32828814, 0.34491032, 0.36153251, 0.3781547 , 0.39477688, 0.41139907, 0.42802125, 0.44464344, 0.46126559, 0.47788778, 0.49450997, 0.51113212, 0.52775431, 0.54437649, 0.56099868, 0.57762086, @@ -999,46 +992,44 @@ array([ 0.2617994 , 0.27842158, 0.29504377, 0.31166595, 0.32828814, 1.00979757, 1.02641988, 1.04304194, 1.05966425, 1.07628632, 1.09290862, 1.10953069, 1.12615299, 1.14277506, 1.15939736, 1.17601943, 1.19264174, 1.2092638 , 1.22588611, 1.24250817, - 1.25913048, 1.27575254, 1.29237485, 1.30899692], dtype=float32) -{'checksum': 14307, - 'note': '', - 'noteSize': 0, - 'pictSize': 0, - 'version': 2, - 'wfmSize': 382} -{'aModified': 0, - 'bname': array(['a', 'n', 'g', 'l', 'e', 'Q', '1', '', '', '', '', '', '', '', '', - '', '', '', '', ''], - dtype='|S1'), - 'botFullScale': 0.0, - 'creationDate': 0, - 'dataUnits': array(['', '', '', ''], - dtype='|S1'), - 'depID': 0, - 'fileName': 0, - 'formula': 0, - 'fsValid': 0, - 'hsA': 1.0, - 'hsB': 0.0, - 'kindBits': '\x00', - 'modDate': 2845473705, - 'next': 0, - 'npnts': 64, - 'srcFldr': 0, - 'swModified': 0, - 'topFullScale': 0.0, - 'type': 2, - 'useBits': '\x00', - 'wData': array([ 0.2617994 , 0.27842158, 0.29504377, 0.31166595]), - 'wModified': 0, - 'wUnused': array(['', ''], - dtype='|S1'), - 'waveNoteH': 0, - 'whVersion': 0, - 'xUnits': array(['', '', '', ''], - dtype='|S1')} + 1.25913048, 1.27575254, 1.29237485, 1.30899692], dtype=float32), + 'wave_header': {'aModified': 0, + 'bname': 'angleQ1', + 'botFullScale': 0.0, + 'creationDate': 0, + 'dataUnits': array(['', '', '', ''], + dtype='|S1'), + 'depID': 0, + 'fileName': 0, + 'formula': 0, + 'fsValid': 0, + 'hsA': 1.0, + 'hsB': 0.0, + 'kindBits': '\x00', + 'modDate': 2845473705, + 'next': 0, + 'npnts': 64, + 'srcFldr': 0, + 'swModified': 0, + 'topFullScale': 0.0, + 'type': 2, + 'useBits': '\x00', + 'wModified': 0, + 'wUnused': array(['', ''], + dtype='|S1'), + 'waveNoteH': 0, + 'whVersion': 0, + 'xUnits': array(['', '', '', ''], + dtype='|S1')}}} record 37: -array([ -8.34064484, -7.66960144, -6.62294245, -6.82878971, +{'version': 2, + 'wave': {'bin_header': {'checksum': -12080, + 'noteSize': 0, + 'pictSize': 0, + 'wfmSize': 382}, + 'note': '', + 'padding': array([], dtype=float64), + 'wData': array([ -8.34064484, -7.66960144, -6.62294245, -6.82878971, -8.6383152 , -11.20019722, -13.83398628, -15.95139503, -16.18096733, -13.58062267, -9.26843071, -5.34649038, -3.01010084, -2.30953455, -2.73682952, -3.72112942, @@ -1053,46 +1044,54 @@ array([ -8.34064484, -7.66960144, -6.62294245, -6.82878971, -4.54975414, -4.52917624, -3.99160147, -3.1971693 , -2.93472862, -3.47230864, -4.7322526 , -6.80173016, -9.08601665, -10.00928402, -8.87677383, -6.88120317, - -5.61007977, -5.6351161 , -6.41880989, -6.8738699 ], dtype=float32) -{'checksum': -12080, - 'note': '', - 'noteSize': 0, - 'pictSize': 0, - 'version': 2, - 'wfmSize': 382} -{'aModified': 0, - 'bname': array(['r', 'a', 'd', 'i', 'u', 's', 'Q', '1', '', '', '', '', '', '', '', - '', '', '', '', ''], - dtype='|S1'), - 'botFullScale': 0.0, - 'creationDate': 0, - 'dataUnits': array(['', '', '', ''], - dtype='|S1'), - 'depID': 0, - 'fileName': 0, - 'formula': 0, - 'fsValid': 0, - 'hsA': 1.0, - 'hsB': 0.0, - 'kindBits': '\x00', - 'modDate': 2845473634, - 'next': 0, - 'npnts': 64, - 'srcFldr': 0, - 'swModified': 0, - 'topFullScale': 0.0, - 'type': 2, - 'useBits': '\x00', - 'wData': array([-8.34064484, -7.66960144, -6.62294245, -6.82878971]), - 'wModified': 0, - 'wUnused': array(['', ''], - dtype='|S1'), - 'waveNoteH': 0, - 'whVersion': 0, - 'xUnits': array(['', '', '', ''], - dtype='|S1')} + -5.61007977, -5.6351161 , -6.41880989, -6.8738699 ], dtype=float32), + 'wave_header': {'aModified': 0, + 'bname': 'radiusQ1', + 'botFullScale': 0.0, + 'creationDate': 0, + 'dataUnits': array(['', '', '', ''], + dtype='|S1'), + 'depID': 0, + 'fileName': 0, + 'formula': 0, + 'fsValid': 0, + 'hsA': 1.0, + 'hsB': 0.0, + 'kindBits': '\x00', + 'modDate': 2845473634, + 'next': 0, + 'npnts': 64, + 'srcFldr': 0, + 'swModified': 0, + 'topFullScale': 0.0, + 'type': 2, + 'useBits': '\x00', + 'wModified': 0, + 'wUnused': array(['', ''], + dtype='|S1'), + 'waveNoteH': 0, + 'whVersion': 0, + 'xUnits': array(['', '', '', ''], + dtype='|S1')}}} record 38: -array([ 30.58058929, 31.08536911, 31.93481636, 31.57315445, +{'version': 5, + 'wave': {'bin_header': {'checksum': -5745, + 'dataEUnitsSize': 0, + 'dimEUnitsSize': array([0, 0, 0, 0]), + 'dimLabelsSize': array([0, 0, 0, 0]), + 'formulaSize': 78, + 'noteSize': 0, + 'optionsSize1': 0, + 'optionsSize2': 0, + 'sIndicesSize': 0, + 'wfmSize': 576}, + 'data_units': '', + 'dimension_units': '', + 'formula': ' PolarRadiusFunction(radiusQ1,1,-40) * cos(PolarAngleFunction(angleQ1,2,2,2))', + 'labels': [[], [], [], []], + 'note': '', + 'sIndices': array([], dtype=float64), + 'wData': array([ 30.58058929, 31.08536911, 31.93481636, 31.57315445, 29.68683434, 27.10366058, 24.47453499, 22.3495121 , 21.98692894, 24.21500397, 27.95923996, 31.28394508, 33.12408066, 33.46794128, 32.79909515, 31.64211464, @@ -1107,70 +1106,68 @@ array([ 30.58058929, 31.08536911, 31.93481636, 31.57315445, 17.34101677, 16.83446693, 16.56042671, 16.38027191, 15.94310474, 15.16159916, 14.10328865, 12.76812935, 11.41363049, 10.60795975, 10.52314186, 10.67826462, - 10.5454855 , 9.99268055, 9.22939587, 8.5736742 ], dtype=float32) -{'checksum': -5745, - 'dataEUnits': '', - 'dataEUnitsSize': 0, - 'dimEUnits': ['', '', '', ''], - 'dimEUnitsSize': array([0, 0, 0, 0]), - 'dimLabels': [[], [], [], []], - 'dimLabelsSize': array([0, 0, 0, 0]), - 'formula': 'PolarRadiusFunction(radiusQ1,1,-40) * cos(PolarAngleFunction(angleQ1,2,2,2))\x00', - 'formulaSize': 78, - 'note': '', - 'noteSize': 0, - 'optionsSize1': 0, - 'optionsSize2': 0, - 'sIndicesSize': 0, - 'version': 5, - 'wfmSize': 576} -{'aModified': 0, - 'bname': array(['W', '_', 'p', 'l', 'r', 'X', '6', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''], - dtype='|S1'), - 'botFullScale': 0.0, - 'creationDate': 0, - 'dFolder': 7848580, - 'dLock': 0, - 'dataEUnits': 0, - 'dataUnits': array(['', '', '', ''], - dtype='|S1'), - 'depID': 30, - 'dimEUnits': array([0, 0, 0, 0]), - 'dimLabels': array([0, 0, 0, 0]), - 'dimUnits': array([['', '', '', ''], + 10.5454855 , 9.99268055, 9.22939587, 8.5736742 ], dtype=float32), + 'wave_header': {'aModified': 0, + 'bname': 'W_plrX6', + 'botFullScale': 0.0, + 'creationDate': 0, + 'dFolder': 7848580, + 'dLock': 0, + 'dataEUnits': 0, + 'dataUnits': array(['', '', '', ''], + dtype='|S1'), + 'depID': 30, + 'dimEUnits': array([0, 0, 0, 0]), + 'dimLabels': array([0, 0, 0, 0]), + 'dimUnits': array([['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']], dtype='|S1'), - 'fileName': 0, - 'formula': 8052116, - 'fsValid': 0, - 'kindBits': '\x00', - 'modDate': 2985072242, - 'nDim': array([64, 0, 0, 0]), - 'next': 8324392, - 'npnts': 64, - 'sIndices': 0, - 'sfA': array([ 1., 1., 1., 1.]), - 'sfB': array([ 0., 0., 0., 0.]), - 'srcFldr': 0, - 'swModified': 0, - 'topFullScale': 0.0, - 'type': 2, - 'useBits': '\x00', - 'wData': 30.580589294433594, - 'wModified': 0, - 'waveNoteH': 0, - 'whUnused': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - 'whVersion': 1, - 'whpad1': array(['', '', '', '', '', ''], - dtype='|S1'), - 'whpad2': 0, - 'whpad3': 0, - 'whpad4': 0} + 'fileName': 0, + 'formula': 8052116, + 'fsValid': 0, + 'kindBits': '\x00', + 'modDate': 2985072242, + 'nDim': array([64, 0, 0, 0]), + 'next': 8324392, + 'npnts': 64, + 'sIndices': 0, + 'sfA': array([ 1., 1., 1., 1.]), + 'sfB': array([ 0., 0., 0., 0.]), + 'srcFldr': 0, + 'swModified': 0, + 'topFullScale': 0.0, + 'type': 2, + 'useBits': '\x00', + 'wModified': 0, + 'waveNoteH': 0, + 'whUnused': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + 'whVersion': 1, + 'whpad1': array(['', '', '', '', '', ''], + dtype='|S1'), + 'whpad2': 0, + 'whpad3': 0, + 'whpad4': 0}}} record 39: -array([ 8.19404411, 8.88563347, 9.70543861, 10.17177773, +{'version': 5, + 'wave': {'bin_header': {'checksum': -16604, + 'dataEUnitsSize': 0, + 'dimEUnitsSize': array([0, 0, 0, 0]), + 'dimLabelsSize': array([0, 0, 0, 0]), + 'formulaSize': 78, + 'noteSize': 78, + 'optionsSize1': 0, + 'optionsSize2': 0, + 'sIndicesSize': 0, + 'wfmSize': 576}, + 'data_units': '', + 'dimension_units': '', + 'formula': ' PolarRadiusFunction(radiusQ1,1,-40) * sin(PolarAngleFunction(angleQ1,2,2,2))', + 'labels': [[], [], [], []], + 'note': 'shadowX=W_plrX6,appendRadius=radiusQ1,appendAngleData=angleQ1,angleDataUnits=2', + 'sIndices': array([], dtype=float64), + 'wData': array([ 8.19404411, 8.88563347, 9.70543861, 10.17177773, 10.11173058, 9.73756695, 9.25513077, 8.8788929 , 9.16085339, 10.56489944, 12.75579453, 14.90572262, 16.46352959, 17.33401871, 17.68511391, 17.74635315, @@ -1185,137 +1182,154 @@ array([ 8.19404411, 8.88563347, 9.70543861, 10.17177773, 30.91939545, 31.22146797, 31.97431755, 32.95656204, 33.4611969 , 33.23248672, 32.3250885 , 30.64473915, 28.72983551, 28.05199242, 29.29024887, 31.3501091 , - 32.7331543 , 32.87995529, 32.28799438, 31.99738503], dtype=float32) -{'checksum': -16604, - 'dataEUnits': '', - 'dataEUnitsSize': 0, - 'dimEUnits': ['', '', '', ''], - 'dimEUnitsSize': array([0, 0, 0, 0]), - 'dimLabels': [[], [], [], []], - 'dimLabelsSize': array([0, 0, 0, 0]), - 'formula': 'PolarRadiusFunction(radiusQ1,1,-40) * sin(PolarAngleFunction(angleQ1,2,2,2))\x00', - 'formulaSize': 78, - 'note': 'shadowX=W_plrX6,appendRadius=radiusQ1,appendAngleData=angleQ1,angleDataUnits=2', - 'noteSize': 78, - 'optionsSize1': 0, - 'optionsSize2': 0, - 'sIndicesSize': 0, - 'version': 5, - 'wfmSize': 576} -{'aModified': 0, - 'bname': array(['W', '_', 'p', 'l', 'r', 'Y', '6', '', '', '', '', '', '', '', '', - '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''], - dtype='|S1'), - 'botFullScale': 0.0, - 'creationDate': 0, - 'dFolder': 7848580, - 'dLock': 0, - 'dataEUnits': 0, - 'dataUnits': array(['', '', '', ''], - dtype='|S1'), - 'depID': 32, - 'dimEUnits': array([0, 0, 0, 0]), - 'dimLabels': array([0, 0, 0, 0]), - 'dimUnits': array([['', '', '', ''], + 32.7331543 , 32.87995529, 32.28799438, 31.99738503], dtype=float32), + 'wave_header': {'aModified': 0, + 'bname': 'W_plrY6', + 'botFullScale': 0.0, + 'creationDate': 0, + 'dFolder': 7848580, + 'dLock': 0, + 'dataEUnits': 0, + 'dataUnits': array(['', '', '', ''], + dtype='|S1'), + 'depID': 32, + 'dimEUnits': array([0, 0, 0, 0]), + 'dimLabels': array([0, 0, 0, 0]), + 'dimUnits': array([['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']], dtype='|S1'), - 'fileName': 0, - 'formula': 7995612, - 'fsValid': 0, - 'kindBits': '\x00', - 'modDate': 2985072242, - 'nDim': array([64, 0, 0, 0]), - 'next': 0, - 'npnts': 64, - 'sIndices': 0, - 'sfA': array([ 1., 1., 1., 1.]), - 'sfB': array([ 0., 0., 0., 0.]), - 'srcFldr': 0, - 'swModified': 0, - 'topFullScale': 0.0, - 'type': 2, - 'useBits': '\x00', - 'wData': 8.19404411315918, - 'wModified': 0, - 'waveNoteH': 7998208, - 'whUnused': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - 'whVersion': 1, - 'whpad1': array(['', '', '', '', '', ''], - dtype='|S1'), - 'whpad2': 0, - 'whpad3': 0, - 'whpad4': 0} + 'fileName': 0, + 'formula': 7995612, + 'fsValid': 0, + 'kindBits': '\x00', + 'modDate': 2985072242, + 'nDim': array([64, 0, 0, 0]), + 'next': 0, + 'npnts': 64, + 'sIndices': 0, + 'sfA': array([ 1., 1., 1., 1.]), + 'sfB': array([ 0., 0., 0., 0.]), + 'srcFldr': 0, + 'swModified': 0, + 'topFullScale': 0.0, + 'type': 2, + 'useBits': '\x00', + 'wModified': 0, + 'waveNoteH': 7998208, + 'whUnused': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + 'whVersion': 1, + 'whpad1': array(['', '', '', '', '', ''], + dtype='|S1'), + 'whpad2': 0, + 'whpad3': 0, + 'whpad4': 0}}} record 40: 'Packages' record 41: 'WMDataBase' record 42: -{'header': {'numSysVars': 21, - 'numUserStrs': 6, - 'numUserVars': 0, - 'version': 1}, - 'sysVars': array([ 0., 0., 0., 0., 0., 0., 0., 0., 0., - 0., 0., 0., 0., 0., 0., 0., 0., 0., - 0., 0., 128.]), - 'userStrs': {'u_dataBase': ';PolarGraph0:,...,useCircles=2,maxArcLine=6;', - 'u_dbBadStringChars': ',;=:', - 'u_dbCurrBag': 'PolarGraph1', - 'u_dbCurrContents': ',appendRadius=radiusQ1,...,useCircles=2,maxArcLine=6;', - 'u_dbReplaceBadChars': '\xa9\xae\x99\x9f', - 'u_str': '2'}, - 'userVars': {}} +{'variables': {'sysVars': {'K0': 0.0, + 'K1': 0.0, + 'K10': 0.0, + 'K11': 0.0, + 'K12': 0.0, + 'K13': 0.0, + 'K14': 0.0, + 'K15': 0.0, + 'K16': 0.0, + 'K17': 0.0, + 'K18': 0.0, + 'K19': 0.0, + 'K2': 0.0, + 'K20': 128.0, + 'K3': 0.0, + 'K4': 0.0, + 'K5': 0.0, + 'K6': 0.0, + 'K7': 0.0, + 'K8': 0.0, + 'K9': 0.0}, + 'userStrs': {'u_dataBase': ';PolarGraph0:,...,useCircles=2,maxArcLine=6;', + 'u_dbBadStringChars': ',;=:', + 'u_dbCurrBag': 'PolarGraph1', + 'u_dbCurrContents': ',appendRadius=radiusQ1,...,useCircles=2,maxArcLine=6;', + 'u_dbReplaceBadChars': '\xa9\xae\x99\x9f', + 'u_str': '2'}, + 'userVars': {}, + 'var_header': {'numSysVars': 21, + 'numUserStrs': 6, + 'numUserVars': 0}}, + 'version': 1} record 43: '' record 44: 'PolarGraphs' record 45: -{'header': {'numSysVars': 21, - 'numUserStrs': 10, - 'numUserVars': 28, - 'version': 1}, - 'sysVars': array([ 0., 0., 0., 0., 0., 0., 0., 0., 0., - 0., 0., 0., 0., 0., 0., 0., 0., 0., - 0., 0., 128.]), - 'userStrs': {'u_colorList': 'black;blue;green;cyan;red;magenta;yellow;white;special', - 'u_debugStr': 'Turn Debugging On', - 'u_polAngleAxesWherePop': 'Off;Radius Start;Radius End;Radius Start and End;All Major Radii;At Listed Radii', - 'u_polAngleUnitsPop': 'deg;rad', - 'u_polLineStylePop': 'solid;dash 1;dash 2;dash 3;dash 4;dash 5;dash 6;dash 7;dash 8;dash 9;dash 10;dash 11;dash 12;dash 13;dash 14;dash 15;dash 16;dash 17;', - 'u_polOffOn': 'Off;On', - 'u_polRadAxesWherePop': ' Off; Angle Start; Angle Middle; Angle End; Angle Start and End; 0; 90; 180; -90; 0, 90; 90, 180; -180, -90; -90, 0; 0, 180; 90, -90; 0, 90, 180, -90; All Major Angles; At Listed Angles', - 'u_polRotPop': ' -90; 0; +90; +180', - 'u_popup': '', - 'u_prompt': ''}, - 'userVars': {'V_bottom': 232.0, - 'V_left': 1.0, - 'V_max': 2.4158518093414401, - 'V_min': -2.1848498883412, - 'V_right': 232.0, - 'V_top': 1.0, - 'u_UniqWaveNdx': 8.0, - 'u_UniqWinNdx': 3.0, - 'u_angle0': 0.0, - 'u_angleRange': 6.2831853071795862, - 'u_debug': 0.0, - 'u_majorDelta': 0.0, - 'u_numPlaces': 0.0, - 'u_polAngle0': 0.26179938779914941, - 'u_polAngleRange': 1.0471975511965976, - 'u_polInnerRadius': -20.0, - 'u_polMajorAngleInc': 0.26179938779914941, - 'u_polMajorRadiusInc': 10.0, - 'u_polMinorAngleTicks': 3.0, - 'u_polMinorRadiusTicks': 1.0, - 'u_polOuterRadius': 0.0, - 'u_segsPerMinorArc': 3.0, - 'u_tickDelta': 0.0, - 'u_var': 0.0, - 'u_x1': 11.450159535018935, - 'u_x2': 12.079591517721363, - 'u_y1': 42.732577139459856, - 'u_y2': 45.081649278814126}} +{'variables': {'sysVars': {'K0': 0.0, + 'K1': 0.0, + 'K10': 0.0, + 'K11': 0.0, + 'K12': 0.0, + 'K13': 0.0, + 'K14': 0.0, + 'K15': 0.0, + 'K16': 0.0, + 'K17': 0.0, + 'K18': 0.0, + 'K19': 0.0, + 'K2': 0.0, + 'K20': 128.0, + 'K3': 0.0, + 'K4': 0.0, + 'K5': 0.0, + 'K6': 0.0, + 'K7': 0.0, + 'K8': 0.0, + 'K9': 0.0}, + 'userStrs': {'u_colorList': 'black;blue;green;cyan;red;magenta;yellow;white;special', + 'u_debugStr': 'Turn Debugging On', + 'u_polAngleAxesWherePop': 'Off;Radius Start;Radius End;Radius Start and End;All Major Radii;At Listed Radii', + 'u_polAngleUnitsPop': 'deg;rad', + 'u_polLineStylePop': 'solid;dash 1;dash 2;dash 3;dash 4;dash 5;dash 6;dash 7;dash 8;dash 9;dash 10;dash 11;dash 12;dash 13;dash 14;dash 15;dash 16;dash 17;', + 'u_polOffOn': 'Off;On', + 'u_polRadAxesWherePop': ' Off; Angle Start; Angle Middle; Angle End; Angle Start and End; 0; 90; 180; -90; 0, 90; 90, 180; -180, -90; -90, 0; 0, 180; 90, -90; 0, 90, 180, -90; All Major Angles; At Listed Angles', + 'u_polRotPop': ' -90; 0; +90; +180', + 'u_popup': '', + 'u_prompt': ''}, + 'userVars': {'V_bottom': 232.0, + 'V_left': 1.0, + 'V_max': 2.4158518093414401, + 'V_min': -2.1848498883412, + 'V_right': 232.0, + 'V_top': 1.0, + 'u_UniqWaveNdx': 8.0, + 'u_UniqWinNdx': 3.0, + 'u_angle0': 0.0, + 'u_angleRange': 6.2831853071795862, + 'u_debug': 0.0, + 'u_majorDelta': 0.0, + 'u_numPlaces': 0.0, + 'u_polAngle0': 0.26179938779914941, + 'u_polAngleRange': 1.0471975511965976, + 'u_polInnerRadius': -20.0, + 'u_polMajorAngleInc': 0.26179938779914941, + 'u_polMajorRadiusInc': 10.0, + 'u_polMinorAngleTicks': 3.0, + 'u_polMinorRadiusTicks': 1.0, + 'u_polOuterRadius': 0.0, + 'u_segsPerMinorArc': 3.0, + 'u_tickDelta': 0.0, + 'u_var': 0.0, + 'u_x1': 11.450159535018935, + 'u_x2': 12.079591517721363, + 'u_y1': 42.732577139459856, + 'u_y2': 45.081649278814126}, + 'var_header': {'numSysVars': 21, + 'numUserStrs': 10, + 'numUserVars': 28}}, + 'version': 1} record 46: '' record 47: @@ -1418,18 +1432,16 @@ from igor.record.wave import WaveRecord _this_dir = os.path.dirname(__file__) _data_dir = os.path.join(_this_dir, 'data') -def dumpibw(filename, strict=True): +def dumpibw(filename): sys.stderr.write('Testing {}\n'.format(filename)) path = os.path.join(_data_dir, filename) - data,bin_info,wave_info = loadibw(path, strict=strict) + data = loadibw(path) pprint(data) - pprint(bin_info) - pprint(wave_info) -def dumppxp(filename, strict=True): +def dumppxp(filename): sys.stderr.write('Testing {}\n'.format(filename)) path = os.path.join(_data_dir, filename) - records,filesystem = loadpxp(path, strict=strict) + records,filesystem = loadpxp(path) for i,record in enumerate(records): print('record {}:'.format(i)) if isinstance(record, (FolderStartRecord, FolderEndRecord)): @@ -1440,8 +1452,6 @@ def dumppxp(filename, strict=True): pprint(record.variables) elif isinstance(record, WaveRecord): pprint(record.wave) - pprint(record.bin_info) - pprint(record.wave_info) else: pprint(record) print('\nfilesystem:') -- 2.26.2