From bbfaea5a601a6e358f96fcd0b9040c5cff0e4023 Mon Sep 17 00:00:00 2001 From: Ryuichi Arafune Date: Thu, 8 Jun 2023 01:16:00 +0900 Subject: [PATCH 01/16] Update binarywave.py `np.complex` was a deprecated alias for the builtin `complex` after numpy 1.20. --- igor/binarywave.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/igor/binarywave.py b/igor/binarywave.py index 6d87d14..d557acd 100644 --- a/igor/binarywave.py +++ b/igor/binarywave.py @@ -107,7 +107,7 @@ class NullStaticStringField (StaticStringField): # From IgorMath.h TYPE_TABLE = { # (key: integer flag, value: numpy dtype) 0:None, # Text wave, not handled in ReadWave.c - 1:_numpy.complex, # NT_CMPLX, makes number complex. + 1:complex, # NT_CMPLX, makes number complex. 2:_numpy.float32, # NT_FP32, 32 bit fp numbers. 3:_numpy.complex64, 4:_numpy.float64, # NT_FP64, 64 bit fp numbers. From cd856694880f702e883a940e28fd90bcff4788c7 Mon Sep 17 00:00:00 2001 From: Ryuichi Arafune Date: Tue, 11 Jul 2023 12:29:42 +0900 Subject: [PATCH 02/16] Apply black and remove meaningless underbar. * such as: _LOG -> LOG _sys -> sys, _numpy -> np _argparse -> argparse, _logging -> logging, _sys -> sys --- igor/__init__.py | 13 +- igor/binarywave.py | 931 ++++++++++++++++++++++++++------------ igor/igorpy.py | 259 +++++++---- igor/packed.py | 144 +++--- igor/record/__init__.py | 4 +- igor/record/base.py | 20 +- igor/record/folder.py | 4 +- igor/record/history.py | 6 +- igor/record/packedfile.py | 2 +- igor/record/procedure.py | 2 +- igor/record/variables.py | 370 ++++++++------- igor/record/wave.py | 8 +- igor/script.py | 74 +-- igor/struct.py | 225 ++++----- igor/util.py | 60 +-- 15 files changed, 1307 insertions(+), 815 deletions(-) diff --git a/igor/__init__.py b/igor/__init__.py index 7f0220a..de88127 100644 --- a/igor/__init__.py +++ b/igor/__init__.py @@ -17,14 +17,15 @@ "Interface for reading binary IGOR files." -__version__ = '0.3.1' +__version__ = "0.3.1" -import logging as _logging +import logging -LOG = _logging.getLogger('igor') -LOG.setLevel(_logging.ERROR) -LOG.addHandler(_logging.StreamHandler()) +LOG = logging.getLogger("igor") +LOG.setLevel(logging.ERROR) +LOG.addHandler(logging.StreamHandler()) LOG.handlers[-1].setFormatter( - _logging.Formatter('%(name)s - %(levelname)s - %(message)s')) + logging.Formatter("%(name)s - %(levelname)s - %(message)s") +) diff --git a/igor/binarywave.py b/igor/binarywave.py index d557acd..57f550c 100644 --- a/igor/binarywave.py +++ b/igor/binarywave.py @@ -26,22 +26,17 @@ # 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 + +import numpy as np + +from . import LOG +from .struct import Structure +from .struct import DynamicStructure +from .struct import DynamicField +from .struct import Field +from .util import byte_order from .util import need_to_reorder_bytes as _need_to_reorder_bytes -from .util import checksum as _checksum +from .util import checksum # Numpy doesn't support complex integers by default, see @@ -50,22 +45,21 @@ # So we roll our own types. See # http://docs.scipy.org/doc/numpy/user/basics.rec.html # http://docs.scipy.org/doc/numpy/reference/generated/numpy.dtype.html -complexInt8 = _numpy.dtype([('real', _numpy.int8), ('imag', _numpy.int8)]) -complexInt16 = _numpy.dtype([('real', _numpy.int16), ('imag', _numpy.int16)]) -complexInt32 = _numpy.dtype([('real', _numpy.int32), ('imag', _numpy.int32)]) -complexUInt8 = _numpy.dtype([('real', _numpy.uint8), ('imag', _numpy.uint8)]) -complexUInt16 = _numpy.dtype( - [('real', _numpy.uint16), ('imag', _numpy.uint16)]) -complexUInt32 = _numpy.dtype( - [('real', _numpy.uint32), ('imag', _numpy.uint32)]) +complexInt8 = np.dtype([("real", np.int8), ("imag", np.int8)]) +complexInt16 = np.dtype([("real", np.int16), ("imag", np.int16)]) +complexInt32 = np.dtype([("real", np.int32), ("imag", np.int32)]) +complexUInt8 = np.dtype([("real", np.uint8), ("imag", np.uint8)]) +complexUInt16 = np.dtype([("real", np.uint16), ("imag", np.uint16)]) +complexUInt32 = np.dtype([("real", np.uint32), ("imag", np.uint32)]) -class StaticStringField (_DynamicField): +class StaticStringField(DynamicField): _null_terminated = False _array_size_field = None + def __init__(self, *args, **kwargs): - if 'array' not in kwargs: - kwargs['array'] = True + if "array" not in kwargs: + kwargs["array"] = True super(StaticStringField, self).__init__(*args, **kwargs) def post_unpack(self, parents, data): @@ -77,12 +71,12 @@ def post_unpack(self, parents, data): def _normalize_string(self, d): if isinstance(d, bytes): pass - elif hasattr(d, 'tobytes'): + elif hasattr(d, "tobytes"): d = d.tobytes() - elif hasattr(d, 'tostring'): # Python 2 compatibility + elif hasattr(d, "tostring"): # Python 2 compatibility d = d.tostring() else: - d = b''.join(d) + d = b"".join(d) if self._array_size_field: start = 0 strings = [] @@ -91,212 +85,467 @@ def _normalize_string(self, d): if end > start: strings.append(d[start:end]) if self._null_terminated: - strings[-1] = strings[-1].split(b'\x00', 1)[0] + strings[-1] = strings[-1].split(b"\x00", 1)[0] start = end elif self._null_terminated: - d = d.split(b'\x00', 1)[0] + d = d.split(b"\x00", 1)[0] return d -class NullStaticStringField (StaticStringField): +class NullStaticStringField(StaticStringField): _null_terminated = True # Begin IGOR constants and typedefs from IgorBin.h # From IgorMath.h -TYPE_TABLE = { # (key: integer flag, value: numpy dtype) - 0:None, # Text wave, not handled in ReadWave.c - 1:complex, # NT_CMPLX, makes number complex. - 2:_numpy.float32, # NT_FP32, 32 bit fp numbers. - 3:_numpy.complex64, - 4:_numpy.float64, # NT_FP64, 64 bit fp numbers. - 5:_numpy.complex128, - 8:_numpy.int8, # NT_I8, 8 bit signed integer. Requires Igor Pro - # 2.0 or later. - 9:complexInt8, - 0x10:_numpy.int16,# NT_I16, 16 bit integer numbers. Requires Igor - # Pro 2.0 or later. - 0x11:complexInt16, - 0x20:_numpy.int32,# NT_I32, 32 bit integer numbers. Requires Igor - # Pro 2.0 or later. - 0x21:complexInt32, -# 0x40:None, # NT_UNSIGNED, Makes above signed integers -# # unsigned. Requires Igor Pro 3.0 or later. - 0x48:_numpy.uint8, - 0x49:complexUInt8, - 0x50:_numpy.uint16, - 0x51:complexUInt16, - 0x60:_numpy.uint32, - 0x61:complexUInt32, +TYPE_TABLE = { # (key: integer flag, value: numpy dtype) + 0: None, # Text wave, not handled in ReadWave.c + 1: complex, # NT_CMPLX, makes number complex. + 2: np.float32, # NT_FP32, 32 bit fp numbers. + 3: np.complex64, + 4: np.float64, # NT_FP64, 64 bit fp numbers. + 5: np.complex128, + 8: np.int8, # NT_I8, 8 bit signed integer. Requires Igor Pro + # 2.0 or later. + 9: complexInt8, + 0x10: np.int16, # NT_I16, 16 bit integer numbers. Requires Igor + # Pro 2.0 or later. + 0x11: complexInt16, + 0x20: np.int32, # NT_I32, 32 bit integer numbers. Requires Igor + # Pro 2.0 or later. + 0x21: complexInt32, + # 0x40:None, # NT_UNSIGNED, Makes above signed integers + # # unsigned. Requires Igor Pro 3.0 or later. + 0x48: np.uint8, + 0x49: complexUInt8, + 0x50: np.uint16, + 0x51: complexUInt16, + 0x60: np.uint32, + 0x61: complexUInt32, } # From wave.h MAXDIMS = 4 # From binary.h -BinHeader1 = _Structure( # `version` field pulled out into Wave - name='BinHeader1', +BinHeader1 = Structure( # `version` field pulled out into Wave + name="BinHeader1", fields=[ - _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( # `version` field pulled out into Wave - name='BinHeader2', + 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( # `version` field pulled out into Wave + name="BinHeader2", fields=[ - _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( # `version` field pulled out into Wave - name='BinHeader3', + 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( # `version` field pulled out into Wave + name="BinHeader3", fields=[ - _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( # `version` field pulled out into Wave - name='BinHeader5', + 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( # `version` field pulled out into Wave + name="BinHeader5", fields=[ - _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.'), - _Field('l', 'noteSize', help='The size of the note text.'), - _Field('l', 'dataEUnitsSize', help='The size of optional extended data units.'), - _Field('l', 'dimEUnitsSize', help='The size of optional extended dimension units.', count=MAXDIMS, array=True), - _Field('l', 'dimLabelsSize', help='The size of optional dimension labels.', count=MAXDIMS, array=True), - _Field('l', 'sIndicesSize', help='The size of string indicies if this is a text wave.'), - _Field('l', 'optionsSize1', default=0, help='Reserved. Write zero. Ignore on read.'), - _Field('l', 'optionsSize2', default=0, help='Reserved. Write zero. Ignore on read.'), - ]) + 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."), + Field("l", "noteSize", help="The size of the note text."), + Field("l", "dataEUnitsSize", help="The size of optional extended data units."), + Field( + "l", + "dimEUnitsSize", + help="The size of optional extended dimension units.", + count=MAXDIMS, + array=True, + ), + Field( + "l", + "dimLabelsSize", + help="The size of optional dimension labels.", + count=MAXDIMS, + array=True, + ), + Field( + "l", + "sIndicesSize", + help="The size of string indicies if this is a text wave.", + ), + Field( + "l", "optionsSize1", default=0, help="Reserved. Write zero. Ignore on read." + ), + Field( + "l", "optionsSize2", default=0, help="Reserved. Write zero. Ignore on read." + ), + ], +) # From wave.h -MAX_WAVE_NAME2 = 18 # Maximum length of wave name in version 1 and 2 - # files. Does not include the trailing null. -MAX_WAVE_NAME5 = 31 # Maximum length of wave name in version 5 - # files. Does not include the trailing null. +MAX_WAVE_NAME2 = 18 # Maximum length of wave name in version 1 and 2 +# files. Does not include the trailing null. +MAX_WAVE_NAME5 = 31 # Maximum length of wave name in version 5 +# files. Does not include the trailing null. MAX_UNIT_CHARS = 3 # Header to an array of waveform data. # `wData` field pulled out into DynamicWaveDataField1 -WaveHeader2 = _DynamicStructure( - name='WaveHeader2', +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.'), - 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.'), - _Field('c', 'dataUnits', default=0, help='Natural data units go here - null if none.', count=MAX_UNIT_CHARS+1, array=True), - _Field('c', 'xUnits', default=0, help='Natural x-axis units go here - null if none.', count=MAX_UNIT_CHARS+1, array=True), - _Field('l', 'npnts', help='Number of data points in wave.'), - _Field('h', 'aModified', default=0, help='Used in memory only. Write zero. Ignore on read.'), - _Field('d', 'hsA', help='X value for point p = hsA*p + hsB'), - _Field('d', 'hsB', help='X value for point p = hsA*p + hsB'), - _Field('h', 'wModified', default=0, help='Used in memory only. Write zero. Ignore on read.'), - _Field('h', 'swModified', default=0, help='Used in memory only. Write zero. Ignore on read.'), - _Field('h', 'fsValid', help='True if full scale values have meaning.'), - _Field('d', 'topFullScale', help='The min full scale value for wave.'), # sic, 'min' should probably be 'max' - _Field('d', 'botFullScale', help='The min full scale value for wave.'), - _Field('c', 'useBits', default=0, help='Used in memory only. Write zero. Ignore on read.'), - _Field('c', 'kindBits', default=0, help='Reserved. Write zero. Ignore on read.'), - _Field('P', 'formula', default=0, help='Used in memory only. Write zero. Ignore on read.'), - _Field('l', 'depID', default=0, help='Used in memory only. Write zero. Ignore on read.'), - _Field('L', 'creationDate', help='DateTime of creation. Not used in version 1 files.'), - _Field('c', 'wUnused', default=0, help='Reserved. Write zero. Ignore on read.', count=2, array=True), - _Field('L', 'modDate', help='DateTime of last modification.'), - _Field('P', 'waveNoteH', help='Used in memory only. Write zero. Ignore on read.'), - ]) + 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.", + ), + 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.", + ), + Field( + "c", + "dataUnits", + default=0, + help="Natural data units go here - null if none.", + count=MAX_UNIT_CHARS + 1, + array=True, + ), + Field( + "c", + "xUnits", + default=0, + help="Natural x-axis units go here - null if none.", + count=MAX_UNIT_CHARS + 1, + array=True, + ), + Field("l", "npnts", help="Number of data points in wave."), + Field( + "h", + "aModified", + default=0, + help="Used in memory only. Write zero. Ignore on read.", + ), + Field("d", "hsA", help="X value for point p = hsA*p + hsB"), + Field("d", "hsB", help="X value for point p = hsA*p + hsB"), + Field( + "h", + "wModified", + default=0, + help="Used in memory only. Write zero. Ignore on read.", + ), + Field( + "h", + "swModified", + default=0, + help="Used in memory only. Write zero. Ignore on read.", + ), + Field("h", "fsValid", help="True if full scale values have meaning."), + Field( + "d", "topFullScale", help="The min full scale value for wave." + ), # sic, 'min' should probably be 'max' + Field("d", "botFullScale", help="The min full scale value for wave."), + Field( + "c", + "useBits", + default=0, + help="Used in memory only. Write zero. Ignore on read.", + ), + Field("c", "kindBits", default=0, help="Reserved. Write zero. Ignore on read."), + Field( + "P", + "formula", + default=0, + help="Used in memory only. Write zero. Ignore on read.", + ), + Field( + "l", + "depID", + default=0, + help="Used in memory only. Write zero. Ignore on read.", + ), + Field( + "L", + "creationDate", + help="DateTime of creation. Not used in version 1 files.", + ), + Field( + "c", + "wUnused", + default=0, + help="Reserved. Write zero. Ignore on read.", + count=2, + array=True, + ), + Field("L", "modDate", help="DateTime of last modification."), + Field( + "P", "waveNoteH", help="Used in memory only. Write zero. Ignore on read." + ), + ], +) # `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', +WaveHeader5 = DynamicStructure( + name="WaveHeader5", fields=[ - _Field('P', 'next', help='link to next wave in linked list.'), - _Field('L', 'creationDate', help='DateTime of creation.'), - _Field('L', 'modDate', help='DateTime of last modification.'), - _Field('l', 'npnts', help='Total number of points (multiply dimensions up to first zero).'), - _Field('h', 'type', help='See types (e.g. NT_FP64) above. Zero for text waves.'), - _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, array=True), - _Field('h', 'whVersion', default=1, help='Write 1. Ignore on read.'), - 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.'), + Field("P", "next", help="link to next wave in linked list."), + Field("L", "creationDate", help="DateTime of creation."), + Field("L", "modDate", help="DateTime of last modification."), + Field( + "l", + "npnts", + help="Total number of points (multiply dimensions up to first zero).", + ), + Field("h", "type", help="See types (e.g. NT_FP64) above. Zero for text waves."), + 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, + array=True, + ), + Field("h", "whVersion", default=1, help="Write 1. Ignore on read."), + 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 - _Field('l', 'nDim', help='Number of of items in a dimension -- 0 means no data.', count=MAXDIMS, array=True), - _Field('d', 'sfA', help='Index value for element e of dimension d = sfA[d]*e + sfB[d].', count=MAXDIMS, array=True), - _Field('d', 'sfB', help='Index value for element e of dimension d = sfA[d]*e + sfB[d].', count=MAXDIMS, array=True), + Field( + "l", + "nDim", + help="Number of of items in a dimension -- 0 means no data.", + count=MAXDIMS, + array=True, + ), + Field( + "d", + "sfA", + help="Index value for element e of dimension d = sfA[d]*e + sfB[d].", + count=MAXDIMS, + array=True, + ), + Field( + "d", + "sfB", + help="Index value for element e of dimension d = sfA[d]*e + sfB[d].", + count=MAXDIMS, + array=True, + ), # SI units - _Field('c', 'dataUnits', default=0, help='Natural data units go here - null if none.', count=MAX_UNIT_CHARS+1, array=True), - _Field('c', 'dimUnits', default=0, help='Natural dimension units go here - null if none.', count=(MAXDIMS, MAX_UNIT_CHARS+1), array=True), - _Field('h', 'fsValid', help='TRUE if full scale values have meaning.'), - _Field('h', 'whpad3', default=0, help='Reserved. Write zero. Ignore on read.'), - _Field('d', 'topFullScale', help='The max and max full scale value for wave'), # sic, probably "max and min" - _Field('d', 'botFullScale', help='The max and max full scale value for wave.'), # sic, probably "max and min" - _Field('P', 'dataEUnits', default=0, help='Used in memory only. Write zero. Ignore on read.'), - _Field('P', 'dimEUnits', default=0, help='Used in memory only. Write zero. Ignore on read.', count=MAXDIMS, array=True), - _Field('P', 'dimLabels', default=0, help='Used in memory only. Write zero. Ignore on read.', count=MAXDIMS, array=True), - _Field('P', 'waveNoteH', default=0, help='Used in memory only. Write zero. Ignore on read.'), - _Field('l', 'whUnused', default=0, help='Reserved. Write zero. Ignore on read.', count=16, array=True), + Field( + "c", + "dataUnits", + default=0, + help="Natural data units go here - null if none.", + count=MAX_UNIT_CHARS + 1, + array=True, + ), + Field( + "c", + "dimUnits", + default=0, + help="Natural dimension units go here - null if none.", + count=(MAXDIMS, MAX_UNIT_CHARS + 1), + array=True, + ), + Field("h", "fsValid", help="TRUE if full scale values have meaning."), + Field("h", "whpad3", default=0, help="Reserved. Write zero. Ignore on read."), + Field( + "d", "topFullScale", help="The max and max full scale value for wave" + ), # sic, probably "max and min" + Field( + "d", "botFullScale", help="The max and max full scale value for wave." + ), # sic, probably "max and min" + Field( + "P", + "dataEUnits", + default=0, + help="Used in memory only. Write zero. Ignore on read.", + ), + Field( + "P", + "dimEUnits", + default=0, + help="Used in memory only. Write zero. Ignore on read.", + count=MAXDIMS, + array=True, + ), + Field( + "P", + "dimLabels", + default=0, + help="Used in memory only. Write zero. Ignore on read.", + count=MAXDIMS, + array=True, + ), + Field( + "P", + "waveNoteH", + default=0, + help="Used in memory only. Write zero. Ignore on read.", + ), + Field( + "l", + "whUnused", + default=0, + help="Reserved. Write zero. Ignore on read.", + count=16, + array=True, + ), # The following stuff is considered private to Igor. - _Field('h', 'aModified', default=0, help='Used in memory only. Write zero. Ignore on read.'), - _Field('h', 'wModified', default=0, help='Used in memory only. Write zero. Ignore on read.'), - _Field('h', 'swModified', default=0, help='Used in memory only. Write zero. Ignore on read.'), - _Field('c', 'useBits', default=0, help='Used in memory only. Write zero. Ignore on read.'), - _Field('c', 'kindBits', default=0, help='Reserved. Write zero. Ignore on read.'), - _Field('P', 'formula', default=0, help='Used in memory only. Write zero. Ignore on read.'), - _Field('l', 'depID', default=0, help='Used in memory only. Write zero. Ignore on read.'), - _Field('h', 'whpad4', default=0, help='Reserved. Write zero. 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.'), - _Field('P', 'sIndices', default=0, help='Used in memory only. Write zero. Ignore on read.'), - ]) - - -class DynamicWaveDataField1 (_DynamicField): + Field( + "h", + "aModified", + default=0, + help="Used in memory only. Write zero. Ignore on read.", + ), + Field( + "h", + "wModified", + default=0, + help="Used in memory only. Write zero. Ignore on read.", + ), + Field( + "h", + "swModified", + default=0, + help="Used in memory only. Write zero. Ignore on read.", + ), + Field( + "c", + "useBits", + default=0, + help="Used in memory only. Write zero. Ignore on read.", + ), + Field("c", "kindBits", default=0, help="Reserved. Write zero. Ignore on read."), + Field( + "P", + "formula", + default=0, + help="Used in memory only. Write zero. Ignore on read.", + ), + Field( + "l", + "depID", + default=0, + help="Used in memory only. Write zero. Ignore on read.", + ), + Field("h", "whpad4", default=0, help="Reserved. Write zero. 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.", + ), + Field( + "P", + "sIndices", + default=0, + help="Used in memory only. Write zero. Ignore on read.", + ), + ], +) + + +class DynamicWaveDataField1(DynamicField): def pre_pack(self, parents, data): raise NotImplementedError() def pre_unpack(self, parents, data): - full_structure = parents[0] + 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'] + version = data["version"] + bin_header = wave_data["bin_header"] + wave_header = wave_data["wave_header"] - self.count = wave_header['npnts'] + 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) + 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') + type_ = np.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. - 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): + self.dtype = np.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 @@ -317,15 +566,21 @@ def pre_unpack(self, parents, data): without the actual wave data. """ self.shape = (0,) - elif TYPE_TABLE.get(wave_header['type'], None) is not None: + 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) + self.data_size, + self.count, + self.dtype.itemsize, + self.dtype, + ) else: assert self.data_size >= 0, ( - bin_header['wfmSize'], wave_header_structure.size) + bin_header["wfmSize"], + wave_header_structure.size, + ) def _get_size(self, bin_header, wave_header_size): - return bin_header['wfmSize'] - wave_header_size - 16 + return bin_header["wfmSize"] - wave_header_size - 16 def _get_shape(self, bin_header, wave_header): return (self.count,) @@ -333,33 +588,32 @@ def _get_shape(self, bin_header, wave_header): def unpack(self, stream): data_b = stream.read(self.data_size) try: - data = _numpy.ndarray( + data = np.ndarray( shape=self.shape, dtype=self.dtype, buffer=data_b, - order='F', - ) + order="F", + ) except: - _LOG.error( - 'could not reshape data from {} to {}'.format( - self.shape, data_b)) + LOG.error("could not reshape data from {} to {}".format(self.shape, data_b)) raise return data -class DynamicWaveDataField5 (DynamicWaveDataField1): +class DynamicWaveDataField5(DynamicWaveDataField1): "Adds support for multidimensional data." + def _get_size(self, bin_header, wave_header_size): - return bin_header['wfmSize'] - 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,) + return [n for n in wave_header["nDim"] if n > 0] or (0,) # End IGOR constants and typedefs from IgorBin.h -class DynamicStringField (StaticStringField): +class DynamicStringField(StaticStringField): _size_field = None def pre_unpack(self, parents, data): @@ -374,15 +628,15 @@ def pre_unpack(self, parents, data): 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'] + bin_header = wave_data["bin_header"] return bin_header[self._size_field] -class DynamicWaveNoteField (DynamicStringField): - _size_field = 'noteSize' +class DynamicWaveNoteField(DynamicStringField): + _size_field = "noteSize" -class DynamicDependencyFormulaField (DynamicStringField): +class DynamicDependencyFormulaField(DynamicStringField): """Optional wave dependency formula Excerpted from TN003: @@ -392,13 +646,14 @@ class DynamicDependencyFormulaField (DynamicStringField): dependency formula is "sin(x)". The formula is stored with no trailing null byte. """ - _size_field = 'formulaSize' + + _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): +class DynamicDataUnitsField(DynamicStringField): """Optional extended data units data Excerpted from TN003: @@ -411,10 +666,11 @@ class DynamicDataUnitsField (DynamicStringField): stored using the optional extended data units section of the file. """ - _size_field = 'dataEUnitsSize' + _size_field = "dataEUnitsSize" -class DynamicDimensionUnitsField (DynamicStringField): + +class DynamicDimensionUnitsField(DynamicStringField): """Optional extended dimension units data Excerpted from TN003: @@ -429,11 +685,12 @@ class DynamicDimensionUnitsField (DynamicStringField): 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' + + _size_field = "dimEUnitsSize" _array_size_field = True -class DynamicLabelsField (DynamicStringField): +class DynamicLabelsField(DynamicStringField): """Optional dimension label data From TN003: @@ -451,13 +708,14 @@ class DynamicLabelsField (DynamicStringField): 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' + + _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'] + bin_header = wave_data["bin_header"] d = wave_data[self.name] dim_labels = [] start = 0 @@ -466,13 +724,13 @@ def post_unpack(self, parents, data): if end > start: dim_data = d[start:end] chunks = [] - for i in range(size//32): - chunks.append(dim_data[32*i:32*(i+1)]) - labels = [b''] + for i in range(size // 32): + chunks.append(dim_data[32 * i : 32 * (i + 1)]) + labels = [b""] for chunk in chunks: - labels[-1] = labels[-1] + b''.join(chunk) - if b'\x00' in chunk: - labels.append(b'') + labels[-1] = labels[-1] + b"".join(chunk) + if b"\x00" in chunk: + labels.append(b"") labels.pop(-1) start = end else: @@ -481,21 +739,21 @@ def post_unpack(self, parents, data): wave_data[self.name] = dim_labels -class DynamicStringIndicesDataField (_DynamicField): - """String indices used for text waves only - """ +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'] + 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 + assert TYPE_TABLE[wave_header["type"]] is None, wave_header self.setup() def post_unpack(self, parents, data): @@ -503,45 +761,47 @@ def post_unpack(self, parents, data): 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'] + wave_header = wave_data["wave_header"] + wdata = wave_data["wData"] strings = [] start = 0 - for i,offset in enumerate(wave_data['sIndices']): + for i, offset in enumerate(wave_data["sIndices"]): if offset > start: chars = wdata[start:offset] - strings.append(b''.join(chars)) + strings.append(b"".join(chars)) start = offset elif offset == start: - strings.append(b'') + strings.append(b"") else: - raise ValueError((offset, wave_data['sIndices'])) - wdata = _numpy.array(strings) - shape = [n for n in wave_header['nDim'] if n > 0] or (0,) + raise ValueError((offset, wave_data["sIndices"])) + wdata = np.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)) + LOG.error( + "could not reshape strings from {} to {}".format(shape, wdata.shape) + ) raise - wave_data['wData'] = wdata + wave_data["wData"] = wdata -class DynamicVersionField (_DynamicField): +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 '@=': + 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)) + 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: need_to_reorder_bytes = False @@ -555,12 +815,14 @@ def post_unpack(self, parents, data): elif version == 5: wave_structure.fields[-1].format = Wave5 elif not need_to_reorder_bytes: - raise ValueError( - 'invalid binary wave version: {}'.format(version)) + 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)) + 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() @@ -569,83 +831,164 @@ def post_unpack(self, parents, data): return need_to_reorder_bytes -class DynamicWaveField (_DynamicField): +class DynamicWaveField(DynamicField): def post_unpack(self, parents, data): return raise NotImplementedError() # TODO checksum_size = bin.size + wave.size - wave_structure = parents[-1] + 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) + 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)) + ( + "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, array=True), - ]) -Wave2 = _DynamicStructure( - name='Wave2', +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, + array=True, + ), + ], +) + +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, array=True), - _Field('x', 'padding', help='16 bytes of padding in versions 2 and 3.', count=16, array=True), - DynamicWaveNoteField('c', 'note', help='Optional wave note data', count=0, array=True), - ]) - -Wave3 = _DynamicStructure( - name='Wave3', + 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, + array=True, + ), + Field( + "x", + "padding", + help="16 bytes of padding in versions 2 and 3.", + count=16, + array=True, + ), + DynamicWaveNoteField( + "c", "note", help="Optional wave note data", count=0, array=True + ), + ], +) + +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, array=True), - _Field('x', 'padding', help='16 bytes of padding in versions 2 and 3.', count=16, array=True), - DynamicWaveNoteField('c', 'note', help='Optional wave note data', count=0, array=True), - DynamicDependencyFormulaField('c', 'formula', help='Optional wave dependency formula', count=0, array=True), - ]) - -Wave5 = _DynamicStructure( - name='Wave5', + 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, + array=True, + ), + Field( + "x", + "padding", + help="16 bytes of padding in versions 2 and 3.", + count=16, + array=True, + ), + DynamicWaveNoteField( + "c", "note", help="Optional wave note data", count=0, array=True + ), + DynamicDependencyFormulaField( + "c", "formula", help="Optional wave dependency formula", count=0, array=True + ), + ], +) + +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, array=True), - DynamicDependencyFormulaField('c', 'formula', help='Optional wave dependency formula.', count=0, array=True), - DynamicWaveNoteField('c', 'note', help='Optional wave note data.', count=0, array=True), - DynamicDataUnitsField('c', 'data_units', help='Optional extended data units data.', count=0, array=True), - DynamicDimensionUnitsField('c', 'dimension_units', help='Optional dimension label data', count=0, array=True), - DynamicLabelsField('c', 'labels', help="Optional dimension label data", count=0, array=True), - DynamicStringIndicesDataField('P', 'sIndices', help='Dynamic string indices for text waves.', count=0, array=True), - ]) - -Wave = _DynamicStructure( - name='Wave', + 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, + array=True, + ), + DynamicDependencyFormulaField( + "c", + "formula", + help="Optional wave dependency formula.", + count=0, + array=True, + ), + DynamicWaveNoteField( + "c", "note", help="Optional wave note data.", count=0, array=True + ), + DynamicDataUnitsField( + "c", + "data_units", + help="Optional extended data units data.", + count=0, + array=True, + ), + DynamicDimensionUnitsField( + "c", + "dimension_units", + help="Optional dimension label data", + count=0, + array=True, + ), + DynamicLabelsField( + "c", "labels", help="Optional dimension label data", count=0, array=True + ), + DynamicStringIndicesDataField( + "P", + "sIndices", + help="Dynamic string indices for text waves.", + count=0, + array=True, + ), + ], +) + +Wave = DynamicStructure( + name="Wave", fields=[ - DynamicVersionField('h', 'version', help='Version number for backwards compatibility.'), - DynamicWaveField(Wave1, 'wave', help='The rest of the wave data.'), - ]) + 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'): + if hasattr(filename, "read"): f = filename # filename is actually a stream object else: - f = open(filename, 'rb') + f = open(filename, "rb") try: - Wave.byte_order = '=' + Wave.byte_order = "=" Wave.setup() data = Wave.unpack_stream(f) finally: - if not hasattr(filename, 'read'): + if not hasattr(filename, "read"): f.close() return data diff --git a/igor/igorpy.py b/igor/igorpy.py index b28de2e..9bfbeac 100644 --- a/igor/igorpy.py +++ b/igor/igorpy.py @@ -14,138 +14,188 @@ PTN003.ifn and TN003.ifn. """ from __future__ import absolute_import -import io as _io -import locale as _locale -import re as _re -import sys as _sys +import io +import locale +import re +import sys -import numpy as _numpy +import numpy as np -from .binarywave import MAXDIMS as _MAXDIMS +from .binarywave import MAXDIMS from .packed import load as _load -from .record.base import UnknownRecord as _UnknownRecord -from .record.folder import FolderStartRecord as _FolderStartRecord -from .record.folder import FolderEndRecord as _FolderEndRecord -from .record.history import HistoryRecord as _HistoryRecord -from .record.history import GetHistoryRecord as _GetHistoryRecord -from .record.history import RecreationRecord as _RecreationRecord -from .record.packedfile import PackedFileRecord as _PackedFileRecord -from .record.procedure import ProcedureRecord as _ProcedureRecord -from .record.wave import WaveRecord as _WaveRecord -from .record.variables import VariablesRecord as _VariablesRecord - - -__version__='0.10' - - -ENCODING = _locale.getpreferredencoding() or _sys.getdefaultencoding() -PYKEYWORDS = set(('and','as','assert','break','class','continue', - 'def','elif','else','except','exec','finally', - 'for','global','if','import','in','is','lambda', - 'or','pass','print','raise','return','try','with', - 'yield')) -PYID = _re.compile(r"^[^\d\W]\w*$", _re.UNICODE) +from .record.base import UnknownRecord +from .record.folder import FolderStartRecord +from .record.folder import FolderEndRecord +from .record.history import HistoryRecord +from .record.history import GetHistoryRecord +from .record.history import RecreationRecord +from .record.packedfile import PackedFileRecord +from .record.procedure import ProcedureRecord +from .record.wave import WaveRecord +from .record.variables import VariablesRecord + + +__version__ = "0.10" + + +ENCODING = locale.getpreferredencoding() or sys.getdefaultencoding() +PYKEYWORDS = set( + ( + "and", + "as", + "assert", + "break", + "class", + "continue", + "def", + "elif", + "else", + "except", + "exec", + "finally", + "for", + "global", + "if", + "import", + "in", + "is", + "lambda", + "or", + "pass", + "print", + "raise", + "return", + "try", + "with", + "yield", + ) +) +PYID = re.compile(r"^[^\d\W]\w*$", re.UNICODE) + + def valid_identifier(s): """Check if a name is a valid identifier""" return PYID.match(s) and s not in PYKEYWORDS class IgorObject(object): - """ Parent class for all objects the parser can return """ + """Parent class for all objects the parser can return""" + pass + class Variables(IgorObject): """ Contains system numeric variables (e.g., K0) and user numeric and string variables. """ + def __init__(self, record): - self.sysvar = record.variables['variables']['sysVars'] - self.uservar = record.variables['variables']['userVars'] - self.userstr = record.variables['variables']['userStrs'] - self.depvar = record.variables['variables'].get('dependentVars', {}) - self.depstr = record.variables['variables'].get('dependentStrs', {}) + self.sysvar = record.variables["variables"]["sysVars"] + self.uservar = record.variables["variables"]["userVars"] + self.userstr = record.variables["variables"]["userStrs"] + self.depvar = record.variables["variables"].get("dependentVars", {}) + self.depstr = record.variables["variables"].get("dependentStrs", {}) def format(self, indent=0): - return " "*indent+""\ - %(len(self.sysvar), - len(self.uservar)+len(self.userstr), - len(self.depvar)+len(self.depstr)) + return " " * indent + "" % ( + len(self.sysvar), + len(self.uservar) + len(self.userstr), + len(self.depvar) + len(self.depstr), + ) + class History(IgorObject): """ Contains the experiment's history as plain text. """ + def __init__(self, data): self.data = data + def format(self, indent=0): - return " "*indent+"" + return " " * indent + "" + class Wave(IgorObject): """ Contains the data for a wave """ + def __init__(self, record): - d = record.wave['wave'] - self.name = d['wave_header']['bname'].decode(ENCODING) - self.data = d['wData'] - self.fs = d['wave_header']['fsValid'] - self.fstop = d['wave_header']['topFullScale'] - self.fsbottom = d['wave_header']['botFullScale'] - version = record.wave['version'] - if version in [1,2,3]: - dims = [d['wave_header']['npnts']] + [0]*(_MAXDIMS-1) - sfA = [d['wave_header']['hsA']] + [0]*(_MAXDIMS-1) - sfB = [d['wave_header']['hsB']] + [0]*(_MAXDIMS-1) - self.data_units = [d['wave_header']['dataUnits']] - self.axis_units = [d['wave_header']['xUnits']] + d = record.wave["wave"] + self.name = d["wave_header"]["bname"].decode(ENCODING) + self.data = d["wData"] + self.fs = d["wave_header"]["fsValid"] + self.fstop = d["wave_header"]["topFullScale"] + self.fsbottom = d["wave_header"]["botFullScale"] + version = record.wave["version"] + if version in [1, 2, 3]: + dims = [d["wave_header"]["npnts"]] + [0] * (MAXDIMS - 1) + sfA = [d["wave_header"]["hsA"]] + [0] * (MAXDIMS - 1) + sfB = [d["wave_header"]["hsB"]] + [0] * (MAXDIMS - 1) + self.data_units = [d["wave_header"]["dataUnits"]] + self.axis_units = [d["wave_header"]["xUnits"]] else: - dims = d['wave_header']['nDim'] - sfA = d['wave_header']['sfA'] - sfB = d['wave_header']['sfB'] + dims = d["wave_header"]["nDim"] + sfA = d["wave_header"]["sfA"] + sfB = d["wave_header"]["sfB"] # TODO find example with multiple data units if version == 5: - self.data_units = [d['data_units'].decode(ENCODING)] - self.axis_units = [b''.join(d).decode(ENCODING) - for d in d['wave_header']['dimUnits']] + self.data_units = [d["data_units"].decode(ENCODING)] + self.axis_units = [ + b"".join(d).decode(ENCODING) for d in d["wave_header"]["dimUnits"] + ] else: - self.data_units = [d['data_units'].decode(ENCODING)] - self.axis_units = [d['dimension_units'].decode(ENCODING)] + self.data_units = [d["data_units"].decode(ENCODING)] + self.axis_units = [d["dimension_units"].decode(ENCODING)] - self.data_units.extend(['']*(_MAXDIMS-len(self.data_units))) + self.data_units.extend([""] * (MAXDIMS - len(self.data_units))) self.data_units = tuple(self.data_units) - self.axis_units.extend(['']*(_MAXDIMS-len(self.axis_units))) + self.axis_units.extend([""] * (MAXDIMS - len(self.axis_units))) self.axis_units = tuple(self.axis_units) - self.axis = [_numpy.linspace(b,b + a * (c - 1),c) for a,b,c in zip(sfA, sfB, dims)] - self.formula = d.get('formula', '') - self.notes = d.get('note', '') + self.axis = [ + np.linspace(b, b + a * (c - 1), c) for a, b, c in zip(sfA, sfB, dims) + ] + self.formula = d.get("formula", "") + self.notes = d.get("note", "") + def format(self, indent=0): if isinstance(self.data, list): - type,size = "text", "%d"%len(self.data) + type, size = "text", "%d" % len(self.data) else: - type,size = "data", "x".join(str(d) for d in self.data.shape) - return " "*indent+"%s %s (%s)"%(self.name, type, size) + type, size = "data", "x".join(str(d) for d in self.data.shape) + return " " * indent + "%s %s (%s)" % (self.name, type, size) def __array__(self): return self.data __repr__ = __str__ = lambda s: "" % s.format() + class Recreation(IgorObject): """ Contains the experiment's recreation procedures as plain text. """ + def __init__(self, data): self.data = data + def format(self, indent=0): - return " "*indent + "" + return " " * indent + "" + + class Procedure(IgorObject): """ Contains the experiment's main procedure window text as plain text. """ + def __init__(self, data): self.data = data + def format(self, indent=0): - return " "*indent + "" + return " " * indent + "" + + class GetHistory(IgorObject): """ Not a real record but rather, a message to go back and read the history text. @@ -155,33 +205,44 @@ class GetHistory(IgorObject): GetHistory entry simply says that the Recreation has run, and the History can be restored from the previously saved value. """ + def __init__(self, data): self.data = data + def format(self, indent=0): - return " "*indent + "" + return " " * indent + "" + + class PackedFile(IgorObject): """ Contains the data for a procedure file or notebook in packed form. """ + def __init__(self, data): self.data = data + def format(self, indent=0): - return " "*indent + "" + return " " * indent + "" + + class Unknown(IgorObject): """ Record type not documented in PTN003/TN003. """ + def __init__(self, data, type): self.data = data self.type = type + def format(self, indent=0): - return " "*indent + ""%self.type + return " " * indent + "" % self.type class Folder(IgorObject): """ Hierarchical record container. """ + def __init__(self, path): self.name = path[-1] self.path = path @@ -192,9 +253,9 @@ def __getitem__(self, key): return self.children[key] else: for r in self.children: - if isinstance(r, (Folder,Wave)) and r.name == key: + if isinstance(r, (Folder, Wave)) and r.name == key: return r - raise KeyError("Folder %s does not exist"%key) + raise KeyError("Folder %s does not exist" % key) def __str__(self): return "" % "/".join(self.path) @@ -217,62 +278,64 @@ def append(self, record): pass def format(self, indent=0): - parent = " "*indent+self.name - children = [r.format(indent=indent+2) for r in self.children] - return "\n".join([parent]+children) + parent = " " * indent + self.name + children = [r.format(indent=indent + 2) for r in self.children] + return "\n".join([parent] + children) def loads(s, **kwargs): """Load an igor file from string""" - stream = _io.BytesIO(s) + stream = io.BytesIO(s) return load(stream, **kwargs) + def load(filename, **kwargs): """Load an igor file""" try: packed_experiment = _load( - filename, initial_byte_order=kwargs.pop('initial_byte_order', '=')) + filename, initial_byte_order=kwargs.pop("initial_byte_order", "=") + ) except ValueError as e: - if e.args[0].startswith('not enough data for the next record header'): - raise IOError('invalid record header; bad pxp file?') - elif e.args[0].startswith('not enough data for the next record'): - raise IOError('final record too long; bad pxp file?') + if e.args[0].startswith("not enough data for the next record header"): + raise IOError("invalid record header; bad pxp file?") + elif e.args[0].startswith("not enough data for the next record"): + raise IOError("final record too long; bad pxp file?") raise return _convert(packed_experiment, **kwargs) + def _convert(packed_experiment, ignore_unknown=True): records, filesystem = packed_experiment - stack = [Folder(path=['root'])] + stack = [Folder(path=["root"])] for record in records: - if isinstance(record, _UnknownRecord): + if isinstance(record, UnknownRecord): if ignore_unknown: continue else: - r = Unknown(record.data, type=record.header['recordType']) - elif isinstance(record, _GetHistoryRecord): + r = Unknown(record.data, type=record.header["recordType"]) + elif isinstance(record, GetHistoryRecord): r = GetHistory(record.text) - elif isinstance(record, _HistoryRecord): + elif isinstance(record, HistoryRecord): r = History(record.text) - elif isinstance(record, _PackedFileRecord): + elif isinstance(record, PackedFileRecord): r = PackedFile(record.text) - elif isinstance(record, _ProcedureRecord): + elif isinstance(record, ProcedureRecord): r = Procedure(record.text) - elif isinstance(record, _RecreationRecord): + elif isinstance(record, RecreationRecord): r = Recreation(record.text) - elif isinstance(record, _VariablesRecord): + elif isinstance(record, VariablesRecord): r = Variables(record) - elif isinstance(record, _WaveRecord): + elif isinstance(record, WaveRecord): r = Wave(record) else: r = None - if isinstance(record, _FolderStartRecord): - path = stack[-1].path + [ - record.null_terminated_text.decode(ENCODING)] + if isinstance(record, FolderStartRecord): + path = stack[-1].path + [record.null_terminated_text.decode(ENCODING)] folder = Folder(path) stack[-1].append(folder) stack.append(folder) - elif isinstance(record, _FolderEndRecord): + elif isinstance(record, FolderEndRecord): stack.pop() elif r is None: raise NotImplementedError(record) diff --git a/igor/packed.py b/igor/packed.py index 2035410..5cf9ba6 100644 --- a/igor/packed.py +++ b/igor/packed.py @@ -17,19 +17,19 @@ "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 . import LOG +from .struct import Structure +from .struct import Field from .util import byte_order as _byte_order from .util import need_to_reorder_bytes as _need_to_reorder_bytes from .util import _bytes -from .record import RECORD_TYPE as _RECORD_TYPE -from .record.base import UnknownRecord as _UnknownRecord -from .record.base import UnusedRecord as _UnusedRecord -from .record.folder import FolderStartRecord as _FolderStartRecord -from .record.folder import FolderEndRecord as _FolderEndRecord -from .record.variables import VariablesRecord as _VariablesRecord -from .record.wave import WaveRecord as _WaveRecord +from .record import RECORD_TYPE +from .record.base import UnknownRecord +from .record.base import UnusedRecord +from .record.folder import FolderStartRecord +from .record.folder import FolderEndRecord +from .record.variables import VariablesRecord +from .record.wave import WaveRecord # From PTN003: @@ -40,32 +40,39 @@ # files, you must skip any record with a record type that is not # listed above. -PackedFileRecordHeader = _Structure( - name='PackedFileRecordHeader', +PackedFileRecordHeader = Structure( + name="PackedFileRecordHeader", fields=[ - _Field('H', 'recordType', help='Record type plus superceded flag.'), - _Field('h', 'version', help='Version information depends on the type of record.'), - _Field('l', 'numDataBytes', help='Number of data bytes in the record following this record header.'), - ]) - -#CR_STR = '\x15' (\r) + Field("H", "recordType", help="Record type plus superceded flag."), + Field( + "h", "version", help="Version information depends on the type of record." + ), + Field( + "l", + "numDataBytes", + help="Number of data bytes in the record following this record header.", + ), + ], +) + +# CR_STR = '\x15' (\r) PACKEDRECTYPE_MASK = 0x7FFF # Record type = (recordType & PACKEDREC_TYPE_MASK) SUPERCEDED_MASK = 0x8000 # Bit is set if the record is superceded by - # a later record in the packed file. +# a later record in the packed file. -def load(filename, strict=True, ignore_unknown=True, initial_byte_order='='): +def load(filename, strict=True, ignore_unknown=True, initial_byte_order="="): """ Probably better to actually infer the initial_byte_order, as can be done from the header. For now though we will let the user deal with this. """ - _LOG.debug('loading a packed experiment file from {}'.format(filename)) + LOG.debug("loading a packed experiment file from {}".format(filename)) records = [] - if hasattr(filename, 'read'): + if hasattr(filename, "read"): f = filename # filename is actually a stream object else: - f = open(filename, 'rb') + f = open(filename, "rb") byte_order = None try: while True: @@ -76,46 +83,53 @@ def load(filename, strict=True, ignore_unknown=True, initial_byte_order='='): break if len(b) < PackedFileRecordHeader.size: raise ValueError( - ('not enough data for the next record header ({} < {})' - ).format(len(b), PackedFileRecordHeader.size)) - _LOG.debug('reading a new packed experiment file record') + ("not enough data for the next record header ({} < {})").format( + len(b), PackedFileRecordHeader.size + ) + ) + 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']) + 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)) + LOG.debug( + "get byte order from version: {} (reorder? {})".format( + byte_order, need_to_reorder + ) + ) if need_to_reorder: PackedFileRecordHeader.byte_order = byte_order PackedFileRecordHeader.setup() header = PackedFileRecordHeader.unpack_from(b) - _LOG.debug( - 'reordered version: {}'.format(header['version'])) - data = bytes(f.read(header['numDataBytes'])) - if len(data) < header['numDataBytes']: + LOG.debug("reordered version: {}".format(header["version"])) + data = bytes(f.read(header["numDataBytes"])) + if len(data) < header["numDataBytes"]: raise ValueError( - ('not enough data for the next record ({} < {})' - ).format(len(b), 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'])) + ("not enough data for the next record ({} < {})").format( + len(b), 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'): + LOG.debug("finished loading {} records from {}".format(len(records), filename)) + if not hasattr(filename, "read"): f.close() filesystem = _build_filesystem(records) return (records, filesystem) + def _build_filesystem(records): # From PTN003: """The name must be a valid Igor data folder name. See Object @@ -151,20 +165,20 @@ def _build_filesystem(records): " ' : ; """ - filesystem = {'root': {}} - dir_stack = [('root', filesystem['root'])] + filesystem = {"root": {}} + dir_stack = [("root", filesystem["root"])] for record in records: cwd = dir_stack[-1][-1] - if isinstance(record, _FolderStartRecord): + if isinstance(record, FolderStartRecord): name = record.null_terminated_text cwd[name] = {} dir_stack.append((name, cwd[name])) - elif isinstance(record, _FolderEndRecord): + elif isinstance(record, FolderEndRecord): dir_stack.pop() - elif isinstance(record, (_VariablesRecord, _WaveRecord)): - if isinstance(record, _VariablesRecord): - sys_vars = record.variables['variables']['sysVars'].keys() - for filename,value in record.namespace.items(): + elif isinstance(record, (VariablesRecord, WaveRecord)): + if isinstance(record, VariablesRecord): + 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 @@ -175,23 +189,27 @@ def _build_filesystem(records): _check_filename(dir_stack, filename) cwd[filename] = value else: # WaveRecord - filename = record.wave['wave']['wave_header']['bname'] + filename = record.wave["wave"]["wave_header"]["bname"] _check_filename(dir_stack, filename) cwd[filename] = record return filesystem + def _check_filename(dir_stack, filename): cwd = dir_stack[-1][-1] if filename in cwd: - raise ValueError('collision on name {} in {}'.format( - filename, ':'.join(d for d,cwd in dir_stack))) + raise ValueError( + "collision on name {} in {}".format( + filename, ":".join(d for d, cwd in dir_stack) + ) + ) + def walk(filesystem, callback, dirpath=None): - """Walk a packed experiment filesystem, operating on each key,value pair. - """ + """Walk a packed experiment filesystem, operating on each key,value pair.""" if dirpath is None: dirpath = [] - for key,value in sorted((_bytes(k),v) for k,v in filesystem.items()): + for key, value in sorted((_bytes(k), v) for k, v in filesystem.items()): callback(dirpath, key, value) if isinstance(value, dict): - walk(filesystem=value, callback=callback, dirpath=dirpath+[key]) + walk(filesystem=value, callback=callback, dirpath=dirpath + [key]) diff --git a/igor/record/__init__.py b/igor/record/__init__.py index eafebfb..da3a7d6 100644 --- a/igor/record/__init__.py +++ b/igor/record/__init__.py @@ -18,7 +18,7 @@ "Record parsers for IGOR's packed experiment files." -from .base import Record, UnknownRecord, UnusedRecord +from .base import UnusedRecord from .variables import VariablesRecord from .history import HistoryRecord, RecreationRecord, GetHistoryRecord from .wave import WaveRecord @@ -40,4 +40,4 @@ 8: PackedFileRecord, 9: FolderStartRecord, 10: FolderEndRecord, - } +} diff --git a/igor/record/base.py b/igor/record/base.py index 6b168cf..f5f1c7d 100644 --- a/igor/record/base.py +++ b/igor/record/base.py @@ -16,7 +16,7 @@ # along with igor. If not, see . -class Record (object): +class Record(object): def __init__(self, header, data, byte_order=None): self.header = header self.data = data @@ -26,22 +26,22 @@ def __str__(self): return self.__repr__() def __repr__(self): - return '<{} {}>'.format(self.__class__.__name__, id(self)) + return "<{} {}>".format(self.__class__.__name__, id(self)) -class UnknownRecord (Record): +class UnknownRecord(Record): def __repr__(self): - return '<{}-{} {}>'.format( - self.__class__.__name__, self.header['recordType'], id(self)) + return "<{}-{} {}>".format( + self.__class__.__name__, self.header["recordType"], id(self) + ) -class UnusedRecord (Record): +class UnusedRecord(Record): pass -class TextRecord (Record): +class TextRecord(Record): def __init__(self, *args, **kwargs): super(TextRecord, self).__init__(*args, **kwargs) - self.text = bytes(self.data).replace( - b'\r\n', b'\n').replace(b'\r', b'\n') - self.null_terminated_text = self.text.split(b'\x00', 1)[0] + self.text = bytes(self.data).replace(b"\r\n", b"\n").replace(b"\r", b"\n") + self.null_terminated_text = self.text.split(b"\x00", 1)[0] diff --git a/igor/record/folder.py b/igor/record/folder.py index caaeb54..cfd39d1 100644 --- a/igor/record/folder.py +++ b/igor/record/folder.py @@ -18,9 +18,9 @@ from .base import TextRecord -class FolderStartRecord (TextRecord): +class FolderStartRecord(TextRecord): pass -class FolderEndRecord (TextRecord): +class FolderEndRecord(TextRecord): pass diff --git a/igor/record/history.py b/igor/record/history.py index e5d2199..b02dc4a 100644 --- a/igor/record/history.py +++ b/igor/record/history.py @@ -18,13 +18,13 @@ from .base import TextRecord -class HistoryRecord (TextRecord): +class HistoryRecord(TextRecord): pass -class RecreationRecord (TextRecord): +class RecreationRecord(TextRecord): pass -class GetHistoryRecord (TextRecord): +class GetHistoryRecord(TextRecord): pass diff --git a/igor/record/packedfile.py b/igor/record/packedfile.py index b457f20..8e2148a 100644 --- a/igor/record/packedfile.py +++ b/igor/record/packedfile.py @@ -18,5 +18,5 @@ from .base import Record -class PackedFileRecord (Record): +class PackedFileRecord(Record): pass diff --git a/igor/record/procedure.py b/igor/record/procedure.py index de00e6e..0fa6374 100644 --- a/igor/record/procedure.py +++ b/igor/record/procedure.py @@ -18,5 +18,5 @@ from .base import TextRecord -class ProcedureRecord (TextRecord): +class ProcedureRecord(TextRecord): pass diff --git a/igor/record/variables.py b/igor/record/variables.py index a8eaccf..8db7870 100644 --- a/igor/record/variables.py +++ b/igor/record/variables.py @@ -15,22 +15,22 @@ # You should have received a copy of the GNU Lesser General Public License # along with igor. If not, see . -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 +import io + +from .. import LOG +from ..binarywave import TYPE_TABLE +from ..binarywave import NullStaticStringField +from ..binarywave import DynamicStringField +from ..struct import Structure +from ..struct import DynamicStructure +from ..struct import Field +from ..struct import 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 -class ListedStaticStringField (_NullStaticStringField): +class ListedStaticStringField(NullStaticStringField): """Handle string conversions for multi-count dynamic parents. If a field belongs to a multi-count dynamic parent, the parent is @@ -40,23 +40,7 @@ class ListedStaticStringField (_NullStaticStringField): 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) @@ -64,8 +48,8 @@ def post_unpack(self, parents, data): parent_data[-1][self.name] = d -class ListedDynamicStrDataField (_DynamicStringField, ListedStaticStringField): - _size_field = 'strLen' +class ListedDynamicStrDataField(DynamicStringField, ListedStaticStringField): + _size_field = "strLen" _null_terminated = False def _get_size_data(self, parents, data): @@ -74,10 +58,10 @@ def _get_size_data(self, parents, data): return parent_data[-1][self._size_field] -class DynamicVarDataField (_DynamicField): +class DynamicVarDataField(DynamicField): def __init__(self, *args, **kwargs): - if 'array' not in kwargs: - kwargs['array'] = True + if "array" not in kwargs: + kwargs["array"] = True super(DynamicVarDataField, self).__init__(*args, **kwargs) def pre_pack(self, parents, data): @@ -88,8 +72,8 @@ def post_unpack(self, parents, data): 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) + for i, value in enumerate(data): + key, value = self._normalize_item(i, value) d[key] = value var_data[self.name] = d @@ -97,27 +81,27 @@ def _normalize_item(self, index, value): raise NotImplementedError() -class DynamicSysVarField (DynamicVarDataField): +class DynamicSysVarField(DynamicVarDataField): def _normalize_item(self, index, value): - name = 'K{}'.format(index) + name = "K{}".format(index) return (name, value) -class DynamicUserVarField (DynamicVarDataField): +class DynamicUserVarField(DynamicVarDataField): def _normalize_item(self, index, value): - name = value['name'] - value = value['num'] + name = value["name"] + value = value["num"] return (name, value) -class DynamicUserStrField (DynamicVarDataField): +class DynamicUserStrField(DynamicVarDataField): def _normalize_item(self, index, value): - name = value['name'] - value = value['data'] + name = value["name"] + value = value["data"] return (name, value) -class DynamicVarNumField (_DynamicField): +class DynamicVarNumField(DynamicField): def post_unpack(self, parents, data): parent_structure = parents[-1] parent_data = self._get_structure_data(parents, data, parent_structure) @@ -125,153 +109,217 @@ def post_unpack(self, parents, data): 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'])) + 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']) + return t(num_var["realPart"]) -class DynamicFormulaField (_DynamicStringField): - _size_field = 'formulaLen' +class DynamicFormulaField(DynamicStringField): + _size_field = "formulaLen" _null_terminated = True # From Variables.h -VarHeader1 = _Structure( # `version` field pulled out into VariablesRecord - name='VarHeader1', +VarHeader1 = Structure( # `version` field pulled out into VariablesRecord + name="VarHeader1", fields=[ - _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.'), - ]) + 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( # `version` field pulled out into VariablesRecord - name='VarHeader2', +VarHeader2 = Structure( # `version` field pulled out into VariablesRecord + name="VarHeader2", fields=[ - _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.'), - _Field('h', 'numDependentVars', help='Number of dependent numeric variables -- may be zero.'), - _Field('h', 'numDependentStrs', help='Number of dependent string variables -- may be zero.'), - ]) + 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." + ), + Field( + "h", + "numDependentVars", + help="Number of dependent numeric variables -- may be zero.", + ), + Field( + "h", + "numDependentStrs", + help="Number of dependent string variables -- may be zero.", + ), + ], +) # From Variables.h -UserStrVarRec1 = _DynamicStructure( - name='UserStrVarRec1', +UserStrVarRec1 = DynamicStructure( + name="UserStrVarRec1", fields=[ - ListedStaticStringField('c', 'name', help='Name of the string variable.', count=32), - _Field('h', 'strLen', help='The real size of the following array.'), - ListedDynamicStrDataField('c', 'data'), - ]) + ListedStaticStringField( + "c", "name", help="Name of the string variable.", count=32 + ), + Field("h", "strLen", help="The real size of the following array."), + ListedDynamicStrDataField("c", "data"), + ], +) # From Variables.h -UserStrVarRec2 = _DynamicStructure( - name='UserStrVarRec2', +UserStrVarRec2 = DynamicStructure( + name="UserStrVarRec2", fields=[ - 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'), - ]) + 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"), + ], +) # From Variables.h -VarNumRec = _Structure( - name='VarNumRec', +VarNumRec = Structure( + name="VarNumRec", fields=[ - _Field('h', 'numType', help='Type from binarywave.TYPE_TABLE'), - _Field('d', 'realPart', help='The real part of the number.'), - _Field('d', 'imagPart', help='The imag part if the number is complex.'), - _Field('l', 'reserved', help='Reserved - set to zero.'), - ]) + Field("h", "numType", help="Type from binarywave.TYPE_TABLE"), + Field("d", "realPart", help="The real part of the number."), + Field("d", "imagPart", help="The imag part if the number is complex."), + Field("l", "reserved", help="Reserved - set to zero."), + ], +) # From Variables.h -UserNumVarRec = _DynamicStructure( - name='UserNumVarRec', +UserNumVarRec = DynamicStructure( + name="UserNumVarRec", fields=[ - ListedStaticStringField('c', 'name', help='Name of the string variable.', count=32), - _Field('h', 'type', help='0 = string, 1 = numeric.'), - DynamicVarNumField(VarNumRec, 'num', help='Type and value of the variable if it is numeric. Not used for string.'), - ]) + ListedStaticStringField( + "c", "name", help="Name of the string variable.", count=32 + ), + Field("h", "type", help="0 = string, 1 = numeric."), + DynamicVarNumField( + VarNumRec, + "num", + help="Type and value of the variable if it is numeric. Not used for string.", + ), + ], +) # From Variables.h -UserDependentVarRec = _DynamicStructure( - name='UserDependentVarRec', +UserDependentVarRec = DynamicStructure( + name="UserDependentVarRec", fields=[ - 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.'), - DynamicFormulaField('c', 'formula', help='Start of the dependency formula. A C string including null terminator.'), - ]) - - -class DynamicVarHeaderField (_DynamicField): + 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."), + DynamicFormulaField( + "c", + "formula", + help="Start of the dependency formula. A C string including null terminator.", + ), + ], +) + + +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'] + var_data = self._get_structure_data(parents, data, var_structure) + 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 = 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 = 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'] + 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 = var_structure.get_field("dependentStrs") + dependent_strs_field.count = data["numDependentStrs"] dependent_strs_field.setup() var_structure.setup() -Variables1 = _DynamicStructure( - name='Variables1', +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', + 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, array=True), - _Field(UserDependentVarRec, 'dependentStrs', help='Dependent string variables.', count=0, array=True), - ]) - - -class DynamicVersionField (_DynamicField): + 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, + array=True, + ), + Field( + UserDependentVarRec, + "dependentStrs", + help="Dependent string variables.", + count=0, + array=True, + ), + ], +) + + +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 '@=': + 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)) + LOG.debug( + "get byte order from version: {} (reorder? {})".format( + variables_structure.byte_order, need_to_reorder_bytes + ) + ) else: need_to_reorder_bytes = False @@ -281,12 +329,14 @@ def post_unpack(self, parents, data): elif version == 2: variables_structure.fields[-1].format = Variables2 elif not need_to_reorder_bytes: - raise ValueError( - 'invalid variables record version: {}'.format(version)) + raise ValueError("invalid variables record version: {}".format(version)) if variables_structure.fields[-1].format != old_format: - _LOG.debug('change variables record from {} to {}'.format( - old_format, variables_structure.fields[-1].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() @@ -295,25 +345,29 @@ def post_unpack(self, parents, data): return need_to_reorder_bytes -VariablesRecordStructure = _DynamicStructure( - name='VariablesRecord', +VariablesRecordStructure = DynamicStructure( + name="VariablesRecord", fields=[ - DynamicVersionField('h', 'version', help='Version number for this header.'), - _Field(Variables1, 'variables', help='The rest of the variables data.'), - ]) + DynamicVersionField("h", "version", help="Version number for this header."), + Field(Variables1, "variables", help="The rest of the variables data."), + ], +) -class VariablesRecord (Record): +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.byte_order = "=" VariablesRecordStructure.setup() - stream = _io.BytesIO(bytes(self.data)) + 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)) + 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 49ed20e..07773b6 100644 --- a/igor/record/wave.py +++ b/igor/record/wave.py @@ -15,16 +15,16 @@ # You should have received a copy of the GNU Lesser General Public License # along with igor. If not, see . -from io import BytesIO as _BytesIO +from io import BytesIO -from ..binarywave import load as _loadibw +from ..binarywave import load as loadibw from . import Record -class WaveRecord (Record): +class WaveRecord(Record): def __init__(self, *args, **kwargs): super(WaveRecord, self).__init__(*args, **kwargs) - self.wave = _loadibw(_BytesIO(bytes(self.data))) + self.wave = loadibw(BytesIO(bytes(self.data))) def __str__(self): return str(self.wave) diff --git a/igor/script.py b/igor/script.py index 83fde93..1303d60 100644 --- a/igor/script.py +++ b/igor/script.py @@ -18,51 +18,55 @@ "Common code for scripts distributed with the `igor` package." from __future__ import absolute_import -import argparse as _argparse -import logging as _logging -import sys as _sys +import argparse +import logging +import sys as sys -try: - import matplotlib as _matplotlib - import matplotlib.pyplot as _matplotlib_pyplot -except ImportError as _matplotlib_import_error: - _matplotlib = None +import matplotlib.pyplot as plt from . import __version__ -from . import LOG as _LOG +from . import LOG as LOG -class Script (object): - log_levels = [_logging.ERROR, _logging.WARNING, _logging.INFO, _logging.DEBUG] +class Script(object): + log_levels = [logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG] - def __init__(self, description=None, filetype='IGOR Binary Wave (.ibw) file'): - self.parser = _argparse.ArgumentParser(description=description) + def __init__(self, description=None, filetype="IGOR Binary Wave (.ibw) file"): + self.parser = argparse.ArgumentParser(description=description) self.parser.add_argument( - '--version', action='version', - version='%(prog)s {}'.format(__version__)) + "--version", action="version", version="%(prog)s {}".format(__version__) + ) self.parser.add_argument( - '-f', '--infile', metavar='FILE', default='-', - help='input {}'.format(filetype)) + "-f", + "--infile", + metavar="FILE", + default="-", + help="input {}".format(filetype), + ) self.parser.add_argument( - '-o', '--outfile', metavar='FILE', default='-', - help='file for ASCII output') + "-o", "--outfile", metavar="FILE", default="-", help="file for ASCII output" + ) self.parser.add_argument( - '-p', '--plot', action='store_const', const=True, - help='use Matplotlib to plot any IGOR waves') + "-p", + "--plot", + action="store_const", + const=True, + help="use Matplotlib to plot any IGOR waves", + ) self.parser.add_argument( - '-V', '--verbose', action='count', default=0, - help='increment verbosity') + "-V", "--verbose", action="count", default=0, help="increment verbosity" + ) self._num_plots = 0 def run(self, *args, **kwargs): args = self.parser.parse_args(*args, **kwargs) - if args.infile == '-': - args.infile = _sys.stdin - if args.outfile == '-': - args.outfile = _sys.stdout + if args.infile == "-": + args.infile = sys.stdin + if args.outfile == "-": + args.outfile = sys.stdout if args.verbose > 1: - log_level = self.log_levels[min(args.verbose-1, len(self.log_levels)-1)] - _LOG.setLevel(log_level) + log_level = self.log_levels[min(args.verbose - 1, len(self.log_levels) - 1)] + LOG.setLevel(log_level) self._run(args) self.display_plots() @@ -72,20 +76,18 @@ def _run(self, args): def plot_wave(self, args, wave, title=None): if not args.plot: return # no-op - if not _matplotlib: - raise _matplotlib_import_error if title is None: - title = wave['wave']['wave_header']['bname'] - figure = _matplotlib_pyplot.figure() + title = wave["wave"]["wave_header"]["bname"] + figure = plt.figure() axes = figure.add_subplot(1, 1, 1) axes.set_title(title) try: - axes.plot(wave['wave']['wData'], 'r.') + axes.plot(wave["wave"]["wData"], "r.") except ValueError as error: - _LOG.error('error plotting {}: {}'.format(title, error)) + LOG.error("error plotting {}: {}".format(title, error)) pass self._num_plots += 1 def display_plots(self): if self._num_plots: - _matplotlib_pyplot.show() + plt.show() diff --git a/igor/struct.py b/igor/struct.py index a50ede5..4e29add 100644 --- a/igor/struct.py +++ b/igor/struct.py @@ -24,17 +24,17 @@ """ from __future__ import absolute_import -import io as _io -import logging as _logging -import pprint as _pprint -import struct as _struct +import io +import logging +import pprint +import struct -import numpy as _numpy +import numpy as np -from . import LOG as _LOG +from . import LOG -class Field (object): +class Field(object): """Represent a Structure field. The format argument can be a format character from the ``struct`` @@ -148,8 +148,8 @@ class Field (object): -------- Structure """ - def __init__(self, format, name, default=None, help=None, count=1, - array=False): + + def __init__(self, format, name, default=None, help=None, count=1, array=False): self.format = format self.name = name self.default = default @@ -164,17 +164,18 @@ def setup(self): 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 + LOG.debug("setup {}".format(self)) + self.item_count = np.prod(self.count) # number of item repeats if not self.array and self.item_count != 1: raise ValueError( - '{} must be an array field to have a count of {}'.format( - self, self.count)) + "{} must be an array field to have a count of {}".format( + self, self.count + ) + ) if isinstance(self.format, Structure): - self.structure_count = sum( - f.arg_count for f in self.format.fields) + 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': + elif self.format == "x": self.arg_count = 0 # no data in padding bytes else: self.arg_count = self.item_count # struct.Struct format args @@ -183,8 +184,7 @@ def __str__(self): return self.__repr__() def __repr__(self): - return '<{} {} {}>'.format( - self.__class__.__name__, self.name, id(self)) + return "<{} {} {}>".format(self.__class__.__name__, self.name, id(self)) def indexes(self): """Iterate through indexes to a possibly multi-dimensional array""" @@ -197,7 +197,7 @@ def indexes(self): else: for i in range(self.item_count): index = [] - for j,c in enumerate(reversed(self.count)): + for j, c in enumerate(reversed(self.count)): index.insert(0, i % c) i //= c yield index @@ -211,7 +211,7 @@ def pack_data(self, data=None): if self.array: if data is None: data = [] - if hasattr(data, 'flat'): # take advantage of numpy's ndarray.flat + if hasattr(data, "flat"): # take advantage of numpy's ndarray.flat items = 0 for item in data.flat: items += 1 @@ -219,8 +219,7 @@ def pack_data(self, data=None): yield arg if items < self.item_count: if f.default is None: - raise ValueError( - 'no default for {}.{}'.format(self, f)) + raise ValueError("no default for {}.{}".format(self, f)) for i in range(self.item_count - items): yield f.default else: @@ -241,32 +240,31 @@ def pack_data(self, data=None): yield arg def pack_item(self, item=None): - """Linearize a single count of the field's data to a flat iterable - """ + """Linearize a single count of the field's data to a flat iterable""" if isinstance(self.format, Structure): for i in self.format._pack_item(item): yield i elif item is None: if self.default is None: - raise ValueError('no default for {}'.format(self)) + raise ValueError("no default for {}".format(self)) yield self.default else: yield item def unpack_data(self, data): """Inverse of .pack_data""" - _LOG.debug('unpack {} for {} {}'.format(data, self, self.format)) + LOG.debug("unpack {} for {} {}".format(data, self, self.format)) iterator = iter(data) try: items = [next(iterator) for i in range(self.arg_count)] except StopIteration: - raise ValueError('not enough data to unpack {}'.format(self)) + raise ValueError("not enough data to unpack {}".format(self)) try: next(iterator) except StopIteration: pass else: - raise ValueError('too much data to unpack {}'.format(self)) + raise ValueError("too much data to unpack {}".format(self)) if isinstance(self.format, Structure): # break into per-structure clumps s = self.structure_count @@ -287,11 +285,12 @@ def unpack_data(self, data): except TypeError: pass else: - raise NotImplementedError('reshape Structure field') + raise NotImplementedError("reshape Structure field") else: - unpacked = _numpy.array(unpacked) - _LOG.debug('reshape {} data from {} to {}'.format( - self, unpacked.shape, count)) + unpacked = np.array(unpacked) + LOG.debug( + "reshape {} data from {} to {}".format(self, unpacked.shape, count) + ) unpacked = unpacked.reshape(count) return unpacked @@ -304,7 +303,7 @@ def unpack_item(self, item): return item[0] -class DynamicField (Field): +class DynamicField(Field): """Represent a DynamicStructure field with a dynamic definition. Adds the methods ``.pre_pack``, ``pre_unpack``, and @@ -321,6 +320,7 @@ class DynamicField (Field): -------- Field, DynamicStructure """ + def pre_pack(self, parents, data): "Prepare to pack." pass @@ -334,8 +334,7 @@ def post_unpack(self, parents, data): pass def _get_structure_data(self, parents, data, structure): - """Extract the data belonging to a particular ancestor structure. - """ + """Extract the data belonging to a particular ancestor structure.""" d = data s = parents[0] if s == structure: @@ -352,7 +351,7 @@ def _get_structure_data(self, parents, data, structure): return d -class Structure (_struct.Struct): +class Structure(struct.Struct): r"""Represent a C structure. A convenient wrapper around struct.Struct that uses Fields and @@ -479,9 +478,9 @@ class Structure (_struct.Struct): >>> b2 == b True """ - _byte_order_symbols = '@=<>!' + _byte_order_symbols = "@=<>!" - def __init__(self, name, fields, byte_order='@'): + 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 @@ -493,8 +492,7 @@ def __str__(self): return self.name def __repr__(self): - return '<{} {} {}>'.format( - self.__class__.__name__, self.name, id(self)) + return "<{} {} {}>".format(self.__class__.__name__, self.name, id(self)) def setup(self): """Setup any dynamic properties of a structure. @@ -502,44 +500,41 @@ def setup(self): Use this method to recalculate dynamic properities after changing the basic properties set during initialization. """ - _LOG.debug('setup {!r}'.format(self)) + 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. - """ - _LOG.debug('set byte order for {!r} to {}'.format(self, byte_order)) + """Allow changing the format byte_order on the fly.""" + 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.set_byte_order(byte_order) def get_format(self): - format = self.byte_order + ''.join(self.sub_format()) + 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') + format = format.replace("P", "I") try: super(Structure, self).__init__(format=format) - except _struct.error as e: + except struct.error as e: raise ValueError((e, format)) return format def sub_format(self): - _LOG.debug('calculate sub-format for {!r}'.format(self)) + 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 + field_format = list(field.format.sub_format()) * field.item_count else: - field_format = [field.format]*field.item_count + 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 - """ + """Linearize a single count of the structure's data to a flat iterable""" if item is None: item = {} for f in self.fields: @@ -560,15 +555,14 @@ def _unpack_item(self, args): try: items = [next(iterator) for i in range(f.arg_count)] except StopIteration: - raise ValueError('not enough data to unpack {}.{}'.format( - self, f)) + raise ValueError("not enough data to unpack {}.{}".format(self, f)) data[f.name] = f.unpack_data(items) try: next(iterator) except StopIteration: pass else: - raise ValueError('too much data to unpack {}'.format(self)) + raise ValueError("too much data to unpack {}".format(self)) return data def pack(self, data): @@ -580,37 +574,38 @@ def pack(self, data): def pack_into(self, buffer, offset=0, data={}): args = list(self._pack_item(data)) - return super(Structure, self).pack_into( - buffer, offset, *args) + return super(Structure, self).pack_into(buffer, offset, *args) def unpack(self, *args, **kwargs): args = super(Structure, self).unpack(*args, **kwargs) return self._unpack_item(args) def unpack_from(self, buffer, offset=0, *args, **kwargs): - _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) + 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): +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)) + LOG.debug( + "read {} from {}: ({}) {!r}".format(size, self.stream, len(data), data) + ) return data -class DynamicStructure (Structure): +class DynamicStructure(Structure): r"""Represent a C structure field with a dynamic definition. Any dynamic fields have their ``.pre_pack`` called before any @@ -698,7 +693,7 @@ class DynamicStructure (Structure): for ``Structure``, because we must make multiple calls to ``struct.Struct.unpack`` to unpack the data. """ - #def __init__(self, *args, **kwargs): + # def __init__(self, *args, **kwargs): # pass #self.parent = .. def _pre_pack(self, parents=None, data=None): @@ -707,11 +702,11 @@ def _pre_pack(self, parents=None, data=None): else: parents = parents + [self] for f in self.fields: - if hasattr(f, 'pre_pack'): - _LOG.debug('pre-pack {}'.format(f)) + 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)) + LOG.debug("pre-pack {!r}".format(f.format)) f._pre_pack(parents=parents, data=data) def pack(self, data): @@ -723,29 +718,33 @@ 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) + 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: + 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)) - if _LOG.level <= _logging.DEBUG: - _LOG.debug('data:\n{}'.format(_pprint.pformat(data))) - if hasattr(f, 'pre_unpack'): - _LOG.debug('pre-unpack {}'.format(f)) + LOG.debug( + "parsing {!r}.{} (count={}, item_count={})".format( + self, f, f.count, f.item_count + ) + ) + if LOG.level <= logging.DEBUG: + 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)) + if hasattr(f, "unpack"): # override default unpacking + LOG.debug("override unpack for {}".format(f)) d[f.name] = f.unpack(stream) continue @@ -761,23 +760,28 @@ def unpack_stream(self, stream, parents=None, data=None, d=None): x = {} d[f.name].append(x) f.format.unpack_stream( - stream, parents=parents, data=data, d=x) + stream, parents=parents, data=data, d=x + ) else: assert f.item_count == 1, (f, f.count) d[f.name] = {} f.format.unpack_stream( - stream, parents=parents, data=data, d=d[f.name]) - if hasattr(f, 'post_unpack'): - _LOG.debug('post-unpack {}'.format(f)) + stream, parents=parents, data=data, d=d[f.name] + ) + 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') + "cannot repeat unpack for dynamic structures" + ) continue if isinstance(f.format, Structure): - _LOG.debug('parsing {} bytes for {}'.format( - f.format.size, f.format.format)) + 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() @@ -787,28 +791,32 @@ def unpack(): assert len(x) == 1, (f, f.count, x) x = x[0] return x + else: - field_format = self.byte_order + f.format*f.item_count - field_format = field_format.replace('P', 'I') + 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)) + 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)) + 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)) + "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) + 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) @@ -816,21 +824,20 @@ def unpack(): repeat = True while repeat: d[f.name] = unpack() - if hasattr(f, 'post_unpack'): - _LOG.debug('post-unpack {}'.format(f)) + 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)) + LOG.debug("repeat unpack for {}".format(f)) return data def unpack(self, string): - stream = _io.BytesIO(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) + args = super(Structure, self).unpack_from(buffer, offset, *args, **kwargs) return self._unpack_item(args) diff --git a/igor/util.py b/igor/util.py index ecc783a..8e37eda 100644 --- a/igor/util.py +++ b/igor/util.py @@ -17,9 +17,9 @@ "Utility functions for handling buffers" -import sys as _sys +import sys as sys -import numpy as _numpy +import numpy as np def _ord(byte): @@ -29,11 +29,12 @@ def _ord(byte): >>> [_ord(b) for b in buffer] [0, 1, 2] """ - if _sys.version_info >= (3,): + if sys.version_info >= (3,): return byte else: return ord(byte) + def hex_bytes(buffer, spaces=None): r"""Pretty-printing for binary buffers. @@ -48,14 +49,15 @@ def hex_bytes(buffer, spaces=None): >>> hex_bytes(b'\x00\x01\x02\x03\x04\x05\x06', spaces=3) '000102 030405 06' """ - hex_bytes = ['{:02x}'.format(_ord(x)) for x in buffer] + hex_bytes = ["{:02x}".format(_ord(x)) for x in buffer] if spaces is None: - return ''.join(hex_bytes) - elif spaces is 1: - return ' '.join(hex_bytes) - for i in range(len(hex_bytes)//spaces): - hex_bytes.insert((spaces+1)*(i+1)-1, ' ') - return ''.join(hex_bytes) + return "".join(hex_bytes) + elif spaces == 1: + return " ".join(hex_bytes) + for i in range(len(hex_bytes) // spaces): + hex_bytes.insert((spaces + 1) * (i + 1) - 1, " ") + return "".join(hex_bytes) + def assert_null(buffer, strict=True): r"""Ensure an input buffer is entirely zero. @@ -78,17 +80,20 @@ def assert_null(buffer, strict=True): if strict: raise ValueError(hex_string) else: - _sys.stderr.write( - 'warning: post-data padding not zero: {}\n'.format(hex_string)) + sys.stderr.write( + "warning: post-data padding not zero: {}\n".format(hex_string) + ) + # From ReadWave.c def byte_order(needToReorderBytes): - little_endian = _sys.byteorder == 'little' + little_endian = sys.byteorder == "little" if needToReorderBytes: little_endian = not little_endian if little_endian: - return '<' # little-endian - return '>' # big-endian + return "<" # little-endian + return ">" # big-endian + # From ReadWave.c def need_to_reorder_bytes(version): @@ -98,20 +103,23 @@ def need_to_reorder_bytes(version): # reordered. return version & 0xFF == 0 + # From ReadWave.c def checksum(buffer, byte_order, oldcksum, numbytes): - x = _numpy.ndarray( - (numbytes/2,), # 2 bytes to a short -- ignore trailing odd byte - dtype=_numpy.dtype(byte_order+'h'), - buffer=buffer) + x = np.ndarray( + (numbytes / 2,), # 2 bytes to a short -- ignore trailing odd byte + dtype=np.dtype(byte_order + "h"), + buffer=buffer, + ) oldcksum += x.sum() if oldcksum > 2**31: # fake the C implementation's int rollover oldcksum %= 2**32 if oldcksum > 2**31: oldcksum -= 2**31 - return oldcksum & 0xffff + return oldcksum & 0xFFFF + -def _bytes(obj, encoding='utf-8'): +def _bytes(obj, encoding="utf-8"): """Convert bytes or strings into bytes >>> _bytes(b'123') @@ -119,10 +127,6 @@ def _bytes(obj, encoding='utf-8'): >>> _bytes('123') '123' """ - if _sys.version_info >= (3,): - if isinstance(obj, bytes): - return obj - else: - return bytes(obj, encoding) - else: - return bytes(obj) + if isinstance(obj, bytes): + return obj + return bytes(obj, encoding) From 5d14579330d4857448f599ee64132e975096d2ef Mon Sep 17 00:00:00 2001 From: Ryuichi Arafune Date: Tue, 11 Jul 2023 17:30:24 +0900 Subject: [PATCH 03/16] =?UTF-8?q?=F0=9F=A7=BC=20correction(=F0=9F=93=9C=20?= =?UTF-8?q?stub):=20add=20type=20hints?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add _typing.py to construct TypedDict --- igor/__init__.py | 2 + igor/__init__.pyi | 4 + igor/_typing.py | 55 ++++ igor/binarywave.py | 6 +- igor/binarywave.pyi | 87 +++++ igor/igorpy.py | 4 + igor/igorpy.pyi | 145 +++++++++ igor/packed.py | 11 +- igor/packed.pyi | 36 +++ igor/record/__init__.py | 2 + igor/record/__init__.pyi | 3 + igor/record/base.py | 3 + igor/record/base.pyi | 28 ++ igor/record/folder.py | 2 + igor/record/folder.pyi | 5 + igor/record/history.py | 2 + igor/record/history.pyi | 6 + igor/record/packedfile.py | 2 + igor/record/packedfile.pyi | 5 + igor/record/procedure.py | 2 + igor/record/procedure.pyi | 4 + igor/record/variables.py | 2 + igor/record/variables.pyi | 60 ++++ igor/record/wave.py | 4 +- igor/record/wave.pyi | 12 + igor/script.py | 7 +- igor/script.pyi | 22 ++ igor/struct.py | 35 +- igor/struct.pyi | 157 +++++++++ igor/util.py | 6 +- igor/util.pyi | 11 + test/helper.py | 30 ++ test/test_ibw.py | 631 +++++++++++++++++++++++++++++++++++++ test/test_pxp.py | 433 +++++++++++++++++++++++++ 34 files changed, 1799 insertions(+), 25 deletions(-) create mode 100644 igor/__init__.pyi create mode 100644 igor/_typing.py create mode 100644 igor/binarywave.pyi create mode 100644 igor/igorpy.pyi create mode 100644 igor/packed.pyi create mode 100644 igor/record/__init__.pyi create mode 100644 igor/record/base.pyi create mode 100644 igor/record/folder.pyi create mode 100644 igor/record/history.pyi create mode 100644 igor/record/packedfile.pyi create mode 100644 igor/record/procedure.pyi create mode 100644 igor/record/variables.pyi create mode 100644 igor/record/wave.pyi create mode 100644 igor/script.pyi create mode 100644 igor/struct.pyi create mode 100644 igor/util.pyi create mode 100644 test/helper.py create mode 100644 test/test_ibw.py create mode 100644 test/test_pxp.py diff --git a/igor/__init__.py b/igor/__init__.py index de88127..a9e393d 100644 --- a/igor/__init__.py +++ b/igor/__init__.py @@ -15,6 +15,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with igor. If not, see . +# Memo: there is a difference with igor2 + "Interface for reading binary IGOR files." __version__ = "0.3.1" diff --git a/igor/__init__.pyi b/igor/__init__.pyi new file mode 100644 index 0000000..dd79831 --- /dev/null +++ b/igor/__init__.pyi @@ -0,0 +1,4 @@ +from __future__ import annotations +from _typeshed import Incomplete + +LOG: Incomplete diff --git a/igor/_typing.py b/igor/_typing.py new file mode 100644 index 0000000..fc4a0ef --- /dev/null +++ b/igor/_typing.py @@ -0,0 +1,55 @@ +import numpy as np +from typing import TypedDict, TypeAlias, Literal +from numpy.typing import NDArray + + +from _typeshed import Incomplete +from .record.base import UnknownRecord +from .record.folder import FolderStartRecord +from .record.folder import FolderEndRecord +from .record.history import HistoryRecord +from .record.history import GetHistoryRecord +from .record.history import RecreationRecord +from .record.packedfile import PackedFileRecord +from .record.procedure import ProcedureRecord +from .record.wave import WaveRecord +from .record.variables import VariablesRecord + +BYTEORDER = Literal[">", "<", "=", "@", "!", ""] + + +class WAVETYPE(TypedDict, total=False): + binheader: dict[str, int | NDArray[np.int_]] + waveheader: dict[ + str, + str | bytes | float | NDArray[np.str_] | NDArray[np.int_] | NDArray[np.float_], + ] + wData: NDArray[np.float_] | NDArray[np.complex_] + formula: bytes + note: bytes + data_units: bytes + dimension_units: bytes + labels: list[list[Incomplete]] + sIndics: NDArray[np.float_] + + +class IBW(TypedDict, total=False): + version: int + wave: WAVETYPE + + +class PXP(TypedDict, total=False): + pass + + +RECORDS: TypeAlias = list[ + UnknownRecord + | VariablesRecord + | HistoryRecord + | WaveRecord + | FolderStartRecord + | FolderEndRecord + | RecreationRecord + | ProcedureRecord + | GetHistoryRecord +] diff --git a/igor/binarywave.py b/igor/binarywave.py index 57f550c..5f1d249 100644 --- a/igor/binarywave.py +++ b/igor/binarywave.py @@ -15,6 +15,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with igor. If not, see . +# Memo not essential diff + "Read IGOR Binary Wave files into Numpy arrays." # Based on WaveMetric's Technical Note 003, "Igor Binary Format" @@ -57,7 +59,7 @@ class StaticStringField(DynamicField): _null_terminated = False _array_size_field = None - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: if "array" not in kwargs: kwargs["array"] = True super(StaticStringField, self).__init__(*args, **kwargs) @@ -199,7 +201,7 @@ class NullStaticStringField(StaticStringField): Field( "l", "sIndicesSize", - help="The size of string indicies if this is a text wave.", + help="The size of string indices if this is a text wave.", ), Field( "l", "optionsSize1", default=0, help="Reserved. Write zero. Ignore on read." diff --git a/igor/binarywave.pyi b/igor/binarywave.pyi new file mode 100644 index 0000000..80bc101 --- /dev/null +++ b/igor/binarywave.pyi @@ -0,0 +1,87 @@ +from __future__ import annotations +from typing import BinaryIO +from . import LOG as LOG +from .struct import DynamicField, DynamicStructure, Structure +from _typeshed import Incomplete +from pathlib import Path +from numpy.typing import DTypeLike +from ._typing import IBW, BYTEORDER + +complexInt8: DTypeLike +complexInt16: DTypeLike +complexInt32: DTypeLike +complexUInt8: DTypeLike +complexUInt16: DTypeLike +complexUInt32: DTypeLike + +class StaticStringField(DynamicField): + def __init__( + self, *args: str | Structure | int, **kwargs: str | int | bool + ) -> None: ... + def post_unpack(self, parents: type, data: bytes) -> None: ... + +class NullStaticStringField(StaticStringField): ... + +TYPE_TABLE: dict[int, DTypeLike] +MAXDIMS: int +BinHeader1: Structure +BinHeader2: Structure +BinHeader3: Structure +BinHeader5: Structure +MAX_WAVE_NAME2: int +MAX_WAVE_NAME5: int +MAX_UNIT_CHARS: int +WaveHeader2: DynamicStructure +WaveHeader5: DynamicStructure + +class DynamicWaveDataField1(DynamicField): + def pre_pack(self, parents: type, data: bytes) -> None: ... + + count: Incomplete + data_size: Incomplete + shape: Incomplete + dtype: Incomplete + + def pre_unpack(self, parents: type, data: bytes) -> None: ... + def unpack(self, stream: BinaryIO): ... + +class DynamicWaveDataField5(DynamicWaveDataField1): ... + +class DynamicStringField(StaticStringField): + counts: Incomplete + count: Incomplete + + def pre_unpack(self, parents: type, data: bytes) -> None: ... + +class DynamicWaveNoteField(DynamicStringField): ... +class DynamicDependencyFormulaField(DynamicStringField): ... +class DynamicDataUnitsField(DynamicStringField): ... +class DynamicDimensionUnitsField(DynamicStringField): ... + +class DynamicLabelsField(DynamicStringField): + def post_unpack(self, parents: type, data: bytes) -> None: ... + +class DynamicStringIndicesDataField(DynamicField): + def pre_pack(self, parents: type, data: bytes) -> None: ... + + string_indices_size: Incomplete + count: Incomplete + + def pre_unpack(self, parents: type, data: bytes) -> None: ... + def post_unpack(self, parents: type, data: bytes) -> None: ... + +class DynamicVersionField(DynamicField): + def pre_pack(self, parents: type, byte_order: BYTEORDER) -> None: ... + def post_unpack(self, parents: type, data: bytes): ... + +class DynamicWaveField(DynamicField): + def post_unpack(self, parents: type, data: bytes) -> None: ... + +Wave1: DynamicStructure +Wave2: DynamicStructure +Wave3: DynamicStructure +Wave5: DynamicStructure +Wave: DynamicStructure + +def load(filename: str | Path) -> IBW: ... +def save(filename: str) -> None: ... diff --git a/igor/igorpy.py b/igor/igorpy.py index 9bfbeac..593819d 100644 --- a/igor/igorpy.py +++ b/igor/igorpy.py @@ -13,6 +13,10 @@ The usual igor folder types are given in the technical reports PTN003.ifn and TN003.ifn. """ + +# Memo no related file in igor2 + + from __future__ import absolute_import import io import locale diff --git a/igor/igorpy.pyi b/igor/igorpy.pyi new file mode 100644 index 0000000..61dd769 --- /dev/null +++ b/igor/igorpy.pyi @@ -0,0 +1,145 @@ +from __future__ import annotations +import re + +from _typeshed import Incomplete + +from .binarywave import MAXDIMS +from .packed import load +from .record.base import UnknownRecord +from .record.folder import FolderEndRecord, FolderStartRecord +from .record.history import GetHistoryRecord, HistoryRecord, RecreationRecord +from .record.packedfile import PackedFileRecord +from .record.procedure import ProcedureRecord +from .record.variables import VariablesRecord +from .record.wave import WaveRecord + +ENCODING: str +PYKEYWORDS: set[str] +PYID: re.Pattern + + +def valid_identifier(s): + ... + + +class IgorObject: + ... + + +class Variables(IgorObject): + sysvar: Incomplete + uservar: Incomplete + userstr: Incomplete + depvar: Incomplete + depstr: Incomplete + + def __init__(self, record) -> None: + ... + + def format(self, indent: int = ...): + ... + + +class History(IgorObject): + data: Incomplete + + def __init__(self, data) -> None: + ... + + def format(self, indent: int = ...): + ... + + +class Wave(IgorObject): + name: Incomplete + data: Incomplete + fs: Incomplete + fstop: Incomplete + fsbottom: Incomplete + data_units: Incomplete + axis_units: Incomplete + axis: Incomplete + formula: Incomplete + notes: Incomplete + + def __init__(self, record) -> None: + ... + + def format(self, indent: int = ...): + ... + + def __array__(self): + ... + + +class Recreation(IgorObject): + data: Incomplete + + def __init__(self, data) -> None: + ... + + def format(self, indent: int = ...): + ... + + +class Procedure(IgorObject): + data: Incomplete + + def __init__(self, data) -> None: + ... + + def format(self, indent: int = ...): + ... + + +class GetHistory(IgorObject): + data: Incomplete + + def __init__(self, data) -> None: + ... + + def format(self, indent: int = ...): + ... + + +class PackedFile(IgorObject): + data: Incomplete + + def __init__(self, data) -> None: + ... + + def format(self, indent: int = ...): + ... + + +class Unknown(IgorObject): + data: Incomplete + type: Incomplete + + def __init__(self, data, type) -> None: + ... + + def format(self, indent: int = ...): + ... + + +class Folder(IgorObject): + name: Incomplete + path: Incomplete + children: Incomplete + + def __init__(self, path) -> None: + ... + + def __getitem__(self, key): + ... + + def append(self, record) -> None: + ... + + def format(self, indent: int = ...): + ... + + +def loads(s, **kwargs): + ... diff --git a/igor/packed.py b/igor/packed.py index 5cf9ba6..3c9f995 100644 --- a/igor/packed.py +++ b/igor/packed.py @@ -15,6 +15,9 @@ # You should have received a copy of the GNU Lesser General Public License # along with igor. If not, see . +# Memo essentially no diff with igor2 + + "Read IGOR Packed Experiment files files into records." from . import LOG @@ -43,7 +46,7 @@ PackedFileRecordHeader = Structure( name="PackedFileRecordHeader", fields=[ - Field("H", "recordType", help="Record type plus superceded flag."), + Field("H", "recordType", help="Record type plus superseded flag."), Field( "h", "version", help="Version information depends on the type of record." ), @@ -58,11 +61,11 @@ # CR_STR = '\x15' (\r) PACKEDRECTYPE_MASK = 0x7FFF # Record type = (recordType & PACKEDREC_TYPE_MASK) -SUPERCEDED_MASK = 0x8000 # Bit is set if the record is superceded by +SUPERCEDED_MASK = 0x8000 # Bit is set if the record is superseded by # a later record in the packed file. -def load(filename, strict=True, ignore_unknown=True, initial_byte_order="="): +def load(filename, *, strict=True, ignore_unknown=True, initial_byte_order="="): """ Probably better to actually infer the initial_byte_order, as can be done from the header. For now though we will let the user deal with this. @@ -118,7 +121,7 @@ def load(filename, strict=True, ignore_unknown=True, initial_byte_order="="): ) ) if record_type in [UnknownRecord, UnusedRecord] and not ignore_unknown: - raise KeyError("unkown record type {}".format(header["recordType"])) + raise KeyError("unkwon 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)) diff --git a/igor/packed.pyi b/igor/packed.pyi new file mode 100644 index 0000000..f95f4f3 --- /dev/null +++ b/igor/packed.pyi @@ -0,0 +1,36 @@ +from __future__ import annotations +from . import LOG as LOG +from .record import RECORD_TYPE as RECORD_TYPE +from .record.base import UnknownRecord as UnknownRecord, UnusedRecord as UnusedRecord +from .record.folder import ( + FolderEndRecord as FolderEndRecord, + FolderStartRecord as FolderStartRecord, +) +from .record.variables import VariablesRecord as VariablesRecord +from .record.wave import WaveRecord as WaveRecord +from .struct import Field as Field, Structure as Structure +from _typeshed import Incomplete +from pathlib import Path +from typing import Callable +from typing import Any +from ._typing import RECORDS, BYTEORDER + +PackedFileRecordHeader: Incomplete +PACKEDRECTYPE_MASK: int +SUPERCEDED_MASK: int + +IGORDATAFOLDER = dict[ + str | bytes, WaveRecord | float | dict[str | bytes, IGORDATAFOLDER] +] + +def load( + filename: str | Path, + strict: bool = ..., + ignore_unknown: bool = ..., + initial_byte_order: BYTEORDER = ..., +) -> tuple[RECORDS, dict[str, IGORDATAFOLDER]]: ... +def walk( + filesystem: dict[str, IGORDATAFOLDER], + callback: Callable[[Any], Any], + dirpath: list[str | Path] | None = ..., +) -> None: ... diff --git a/igor/record/__init__.py b/igor/record/__init__.py index da3a7d6..e0b41d5 100644 --- a/igor/record/__init__.py +++ b/igor/record/__init__.py @@ -27,6 +27,8 @@ from .folder import FolderStartRecord, FolderEndRecord +# Memo No diff with igor2 + # From PackedFile.h RECORD_TYPE = { 0: UnusedRecord, diff --git a/igor/record/__init__.pyi b/igor/record/__init__.pyi new file mode 100644 index 0000000..2bae41f --- /dev/null +++ b/igor/record/__init__.pyi @@ -0,0 +1,3 @@ +from __future__ import annotations + +RECORD_TYPE: dict[int, type] diff --git a/igor/record/base.py b/igor/record/base.py index f5f1c7d..e194634 100644 --- a/igor/record/base.py +++ b/igor/record/base.py @@ -16,6 +16,9 @@ # along with igor. If not, see . +# Memo No diff with igor2 + + class Record(object): def __init__(self, header, data, byte_order=None): self.header = header diff --git a/igor/record/base.pyi b/igor/record/base.pyi new file mode 100644 index 0000000..6ecb374 --- /dev/null +++ b/igor/record/base.pyi @@ -0,0 +1,28 @@ +from __future__ import annotations + +from .._typing import BYTEORDER + +class Record: + header: dict[str, int] + data: bytes + byte_order: BYTEORDER | None + + def __init__( + self, + header: dict[str, int], + data: bytes, + byte_order: BYTEORDER = ..., + ) -> None: ... + +class UnknownRecord(Record): ... +class UnusedRecord(Record): ... + +class TextRecord(Record): + text: bytes + null_terminated_text: str + + def __init__( + self, + *args: dict[str, int] | bytes | BYTEORDER, + **kwargs: dict[str, int] | bytes | BYTEORDER, + ) -> None: ... diff --git a/igor/record/folder.py b/igor/record/folder.py index cfd39d1..7bf6d74 100644 --- a/igor/record/folder.py +++ b/igor/record/folder.py @@ -15,6 +15,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with igor. If not, see . +# Memo No diff with igor2 + from .base import TextRecord diff --git a/igor/record/folder.pyi b/igor/record/folder.pyi new file mode 100644 index 0000000..094ce77 --- /dev/null +++ b/igor/record/folder.pyi @@ -0,0 +1,5 @@ +from __future__ import annotations +from .base import TextRecord + +class FolderStartRecord(TextRecord): ... +class FolderEndRecord(TextRecord): ... diff --git a/igor/record/history.py b/igor/record/history.py index b02dc4a..48d98d9 100644 --- a/igor/record/history.py +++ b/igor/record/history.py @@ -15,6 +15,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with igor. If not, see . +# Memo No diff with igor2 + from .base import TextRecord diff --git a/igor/record/history.pyi b/igor/record/history.pyi new file mode 100644 index 0000000..6c55048 --- /dev/null +++ b/igor/record/history.pyi @@ -0,0 +1,6 @@ +from __future__ import annotations +from .base import TextRecord as TextRecord + +class HistoryRecord(TextRecord): ... +class RecreationRecord(TextRecord): ... +class GetHistoryRecord(TextRecord): ... diff --git a/igor/record/packedfile.py b/igor/record/packedfile.py index 8e2148a..4f6b5c7 100644 --- a/igor/record/packedfile.py +++ b/igor/record/packedfile.py @@ -15,6 +15,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with igor. If not, see . +# Memo No diff with igor2 + from .base import Record diff --git a/igor/record/packedfile.pyi b/igor/record/packedfile.pyi new file mode 100644 index 0000000..0607e56 --- /dev/null +++ b/igor/record/packedfile.pyi @@ -0,0 +1,5 @@ +from __future__ import annotations + +from .base import Record as Record + +class PackedFileRecord(Record): ... diff --git a/igor/record/procedure.py b/igor/record/procedure.py index 0fa6374..e70c00e 100644 --- a/igor/record/procedure.py +++ b/igor/record/procedure.py @@ -15,6 +15,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with igor. If not, see . +# Memo No diff with igor2 + from .base import TextRecord diff --git a/igor/record/procedure.pyi b/igor/record/procedure.pyi new file mode 100644 index 0000000..cd07cd3 --- /dev/null +++ b/igor/record/procedure.pyi @@ -0,0 +1,4 @@ +from __future__ import annotations +from .base import TextRecord + +class ProcedureRecord(TextRecord): ... diff --git a/igor/record/variables.py b/igor/record/variables.py index 8db7870..d7822fe 100644 --- a/igor/record/variables.py +++ b/igor/record/variables.py @@ -15,6 +15,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with igor. If not, see . +# Memo essentially No diff with igor2 + import io from .. import LOG diff --git a/igor/record/variables.pyi b/igor/record/variables.pyi new file mode 100644 index 0000000..e3d5e67 --- /dev/null +++ b/igor/record/variables.pyi @@ -0,0 +1,60 @@ +from __future__ import annotations +from ..binarywave import DynamicStringField, NullStaticStringField +from ..struct import ( + DynamicField, + DynamicStructure, + Structure, +) +from .base import Record +from _typeshed import Incomplete +from .._typing import BYTEORDER + +class ListedStaticStringField(NullStaticStringField): + def post_unpack(self, parents: type, data: bytes) -> None: ... + +class ListedDynamicStrDataField(DynamicStringField, ListedStaticStringField): ... + +class DynamicVarDataField(DynamicField): + def __init__(self, *args: Incomplete, **kwargs: Incomplete) -> None: ... + def pre_pack(self, parents: Incomplete, data: Incomplete) -> None: ... + def post_unpack(self, parents: Incomplete, data: Incomplete) -> None: ... + +class DynamicSysVarField(DynamicVarDataField): ... +class DynamicUserVarField(DynamicVarDataField): ... +class DynamicUserStrField(DynamicVarDataField): ... + +class DynamicVarNumField(DynamicField): + def post_unpack(self, parents: type, data: bytes) -> None: ... + +class DynamicFormulaField(DynamicStringField): ... + +VarHeader1: Structure +VarHeader2: Structure +UserStrVarRec1: DynamicStructure +UserStrVarRec2: DynamicStructure +VarNumRec: Structure +UserNumVarRec: DynamicStructure +UserDependentVarRec: DynamicStructure + +class DynamicVarHeaderField(DynamicField): + def pre_pack(self, parents: Incomplete, data: Incomplete) -> None: ... + def post_unpack(self, parents: Incomplete, data: Incomplete) -> None: ... + +Variables1: DynamicVarHeaderField +Variables2: DynamicStructure + +class DynamicVersionField(DynamicField): + def pre_pack(self, parents: Incomplete, byte_order: BYTEORDER) -> None: ... + def post_unpack(self, parents: type, data: bytes) -> None: ... + +VariablesRecordStructure: DynamicStructure + +class VariablesRecord(Record): + variables: dict[str, float | dict[str, float | dict[str, float]]] + namespace: dict[str | bytes, float] + + def __init__( + self, + *args: dict[str, int] | bytes | BYTEORDER, + **kwargs: dict[str, int] | bytes | BYTEORDER, + ) -> None: ... diff --git a/igor/record/wave.py b/igor/record/wave.py index 07773b6..92ad78f 100644 --- a/igor/record/wave.py +++ b/igor/record/wave.py @@ -15,10 +15,12 @@ # You should have received a copy of the GNU Lesser General Public License # along with igor. If not, see . +# Memo No diff with igor2 + from io import BytesIO from ..binarywave import load as loadibw -from . import Record +from .base import Record class WaveRecord(Record): diff --git a/igor/record/wave.pyi b/igor/record/wave.pyi new file mode 100644 index 0000000..42f61e9 --- /dev/null +++ b/igor/record/wave.pyi @@ -0,0 +1,12 @@ +from __future__ import annotations +from .base import Record as Record +from .._typing import IBW, BYTEORDER + +class WaveRecord(Record): + wave: IBW + + def __init__( + self, + *args: dict[str, int] | bytes | BYTEORDER, + **kwargs: dict[str, int] | bytes | BYTEORDER, + ) -> None: ... diff --git a/igor/script.py b/igor/script.py index 1303d60..8beaa7c 100644 --- a/igor/script.py +++ b/igor/script.py @@ -15,17 +15,20 @@ # You should have received a copy of the GNU Lesser General Public License # along with igor. If not, see . +# Memo In igor2 there is not the file named script.py + + "Common code for scripts distributed with the `igor` package." from __future__ import absolute_import import argparse import logging -import sys as sys +import sys import matplotlib.pyplot as plt from . import __version__ -from . import LOG as LOG +from . import LOG class Script(object): diff --git a/igor/script.pyi b/igor/script.pyi new file mode 100644 index 0000000..6828c96 --- /dev/null +++ b/igor/script.pyi @@ -0,0 +1,22 @@ +from __future__ import annotations +from . import LOG as LOG +from _typeshed import Incomplete + + +class Script: + log_levels: Incomplete + parser: Incomplete + + def __init__( + self, description: Incomplete | None = ..., filetype: str = ... + ) -> None: + ... + + def run(self, *args, **kwargs) -> None: + ... + + def plot_wave(self, args, wave, title: Incomplete | None = ...) -> None: + ... + + def display_plots(self) -> None: + ... diff --git a/igor/struct.py b/igor/struct.py index 4e29add..2bd90ba 100644 --- a/igor/struct.py +++ b/igor/struct.py @@ -15,6 +15,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with igor. If not, see . +# Memo Diffierence (small but significant) + """Structure and Field classes for declaring structures There are a few formats that can be used to represent the same data, a @@ -22,13 +24,12 @@ format with each field in a single Python list, and a nested format with each field in a hierarchy of Python dictionaries. """ - +from __future__ import annotations from __future__ import absolute_import import io import logging import pprint import struct - import numpy as np from . import LOG @@ -149,11 +150,13 @@ class Field(object): Structure """ - def __init__(self, format, name, default=None, help=None, count=1, array=False): + def __init__( + self, format, name, default=None, help=None, count: int = 1, array: bool = False + ) -> None: self.format = format self.name = name - self.default = default - self.help = help + self.default = default # Seems not to be used + self.help = help # Seems not to be used (?) self.count = count self.array = array self.setup() @@ -161,7 +164,7 @@ def __init__(self, format, name, default=None, help=None, count=1, array=False): def setup(self): """Setup any dynamic properties of a field. - Use this method to recalculate dynamic properities after + Use this method to recalculate dynamic properties after changing the basic properties set during initialization. """ LOG.debug("setup {}".format(self)) @@ -218,10 +221,13 @@ def pack_data(self, data=None): for arg in self.pack_item(item): yield arg if items < self.item_count: + raise NotADirectoryError("Very bad state") + """ if f.default is None: raise ValueError("no default for {}.{}".format(self, f)) for i in range(self.item_count - items): yield f.default + """ else: for index in self.indexes(): try: @@ -304,7 +310,7 @@ def unpack_item(self, item): class DynamicField(Field): - """Represent a DynamicStructure field with a dynamic definition. + r"""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`` @@ -512,7 +518,7 @@ def set_byte_order(self, byte_order): if isinstance(field.format, Structure): field.format.set_byte_order(byte_order) - def get_format(self): + def get_format(self) -> str: 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. @@ -533,7 +539,7 @@ def sub_format(self): for fmt in field_format: yield fmt - def _pack_item(self, item=None): + def _pack_item(self, item: dict | None = None): """Linearize a single count of the structure's data to a flat iterable""" if item is None: item = {} @@ -572,7 +578,9 @@ def pack(self, data): except: raise ValueError(self.format) - def pack_into(self, buffer, offset=0, data={}): + def pack_into( + self, buffer, offset=0, data={} + ): # check !! should data:dict|None = None? args = list(self._pack_item(data)) return super(Structure, self).pack_into(buffer, offset, *args) @@ -696,7 +704,7 @@ class DynamicStructure(Structure): # def __init__(self, *args, **kwargs): # pass #self.parent = .. - def _pre_pack(self, parents=None, data=None): + def _pre_pack(self, parents: list | None = None, data=None): if parents is None: parents = [self] else: @@ -721,7 +729,7 @@ def pack_into(self, buffer, offset=0, data={}): buffer=buffer, offset=offset, data=data ) - def unpack_stream(self, stream, parents=None, data=None, d=None): + def unpack_stream(self, stream, parents=None, data: dict | None = None, d=None): # `d` is the working data directory if data is None: parents = [self] @@ -816,8 +824,7 @@ 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) + items = struct.Struct(field_format).unpack(raw) return f.unpack_data(items) # unpacking loop diff --git a/igor/struct.pyi b/igor/struct.pyi new file mode 100644 index 0000000..d8aedf0 --- /dev/null +++ b/igor/struct.pyi @@ -0,0 +1,157 @@ +from __future__ import annotations +import struct +from _typeshed import Incomplete +from collections.abc import Generator + +from typing import BinaryIO +from collections.abc import Iterable + +from igor.binarywave import ( + DynamicStringIndicesDataField, + DynamicDependencyFormulaField, + DynamicWaveDataField1, + DynamicWaveDataField5, + DynamicWaveNoteField, + NullStaticStringField, + DynamicDataUnitsField, + DynamicDimensionUnitsField, + DynamicLabelsField, +) +from ._typing import IBW, BYTEORDER + + +class Field: + format: str | Structure + name: str + default: int + help: str + count: int + array: bool + + def __init__( + self, + format: str | Structure, + name: str, + default: int | None = ..., + help: str | None = ..., + count: int = ..., + array: bool = ..., + ) -> None: + ... + + item_count: int + structure_count: int + arg_count: int + + def setup(self) -> None: + ... + + def indexes(self) -> Generator[int, None, None]: + ... + + def pack_data(self, data: bytes | None = ...) -> Generator[Incomplete, None, None]: + ... + + def pack_item( + self, item: Iterable | None = ... + ) -> Generator[Incomplete, None, None]: + ... + + def unpack_data(self, data: bytes): + ... + + def unpack_item(self, item): + ... + + +class DynamicField(Field): + def pre_pack(self, parents: type, data: bytes) -> None: + ... + + def pre_unpack(self, parents: type, data: bytes) -> None: + ... + + def post_unpack(self, parents: type, data: bytes) -> None: + ... + + +class Structure(struct.Struct): + name: str + fields: list[ + Field + | NullStaticStringField + | DynamicWaveDataField1 + | DynamicWaveNoteField + | DynamicDependencyFormulaField + | DynamicWaveDataField5 + | DynamicDependencyFormulaField + | DynamicWaveNoteField + | DynamicDataUnitsField + | DynamicDimensionUnitsField + | DynamicLabelsField + | DynamicStringIndicesDataField + ] + byte_order: BYTEORDER + + def __init__(self, name: str, fields, byte_order: BYTEORDER = ...) -> None: + ... + + def setup(self) -> None: + ... + + def set_byte_order(self, byte_order: BYTEORDER) -> None: + ... + + def get_format(self) -> str: + ... + + def sub_format(self) -> Generator[Incomplete, None, None]: + ... + + def pack(self, data: bytes): + ... + + def pack_into(self, buffer, offset: int = ..., data: bytes = ...): + ... + + def unpack(self, *args, **kwargs): + ... + + def unpack_from(self, buffer, offset: int = ..., *args, **kwargs): + ... + + def get_field(self, name: str): + ... + + +class DebuggingStream: + stream: BinaryIO + + def __init__(self, stream: BinaryIO) -> None: + ... + + def read(self, size: int): + ... + + +class DynamicStructure(Structure): + def pack(self, data: bytes) -> bytearray: + ... + + def pack_into(self, buffer, offset: int = ..., data: bytes = ...) -> None: + ... + + def unpack_stream( + self, + stream: BinaryIO, + parents: type | None = ..., + data: dict | None = ..., + d: Incomplete | None = ..., + ) -> IBW: + ... + + def unpack(self, string): + ... + + def unpack_from(self, buffer, offset: int = ..., *args, **kwargs): + ... diff --git a/igor/util.py b/igor/util.py index 8e37eda..d7d455a 100644 --- a/igor/util.py +++ b/igor/util.py @@ -15,6 +15,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with igor. If not, see . +# Memo: No essential diff with igor2 + "Utility functions for handling buffers" import sys as sys @@ -35,7 +37,7 @@ def _ord(byte): return ord(byte) -def hex_bytes(buffer, spaces=None): +def hex_bytes(buffer, spaces: int = 0): r"""Pretty-printing for binary buffers. >>> hex_bytes(b'\x00\x01\x02\x03\x04') @@ -50,7 +52,7 @@ def hex_bytes(buffer, spaces=None): '000102 030405 06' """ hex_bytes = ["{:02x}".format(_ord(x)) for x in buffer] - if spaces is None: + if not spaces: return "".join(hex_bytes) elif spaces == 1: return " ".join(hex_bytes) diff --git a/igor/util.pyi b/igor/util.pyi new file mode 100644 index 0000000..f476f12 --- /dev/null +++ b/igor/util.pyi @@ -0,0 +1,11 @@ +from __future__ import annotations +from _typeshed import Incomplete +from ._typing import BYTEORDER + +def hex_bytes(buffer: Incomplete, spaces: int = ...) -> str: ... +def assert_null(buffer: Incomplete, strict: bool = ...) -> None: ... +def byte_order(needToReorderBytes: bool) -> BYTEORDER: ... +def need_to_reorder_bytes(version: int) -> bool: ... +def checksum( + buffer: Incomplete, byte_order: BYTEORDER, oldcksum: int, numbytes: int +) -> int: ... diff --git a/test/helper.py b/test/helper.py new file mode 100644 index 0000000..8f88bdf --- /dev/null +++ b/test/helper.py @@ -0,0 +1,30 @@ +import pathlib +from pprint import pformat + +from igor.binarywave import load as loadibw + + +data_dir = pathlib.Path(__file__).parent / "data" + + +def assert_equal_dump_no_whitespace_no_byte(data_a, data_b): + a = data_a.replace(" ", "").replace("b'", "'").replace("\n", "") + b = data_b.replace(" ", "").replace("b'", "'").replace("\n", "") + assert a == b + + +def dumpibw(filename): + path = data_dir / filename + data = loadibw(path) + return format_data(data) + + +def format_data(data): + lines = pformat(data).splitlines() + return "\n".join([line.rstrip() for line in lines]) + + +def walk_callback(dirpath, key, value): + return "walk callback on ({}, {}, {})".format( + dirpath, key, "{...}" if isinstance(value, dict) else value + ) diff --git a/test/test_ibw.py b/test/test_ibw.py new file mode 100644 index 0000000..1eb1163 --- /dev/null +++ b/test/test_ibw.py @@ -0,0 +1,631 @@ +from helper import assert_equal_dump_no_whitespace_no_byte, dumpibw + + +def test_ibw01(): + act = dumpibw("mac-double.ibw") # doctest: +REPORT_UDIFF + + exp = """{'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')}}}""" + + assert_equal_dump_no_whitespace_no_byte(act, exp) + + +def test_ibw_02(): + act = dumpibw("mac-textWave.ibw") + + exp = """ + {'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', + '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}}} + """ + + assert_equal_dump_no_whitespace_no_byte(act, exp) + + +def test_ibw_03(): + act = dumpibw("mac-version2.ibw") + exp = """ + {'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')}}} + """ + assert_equal_dump_no_whitespace_no_byte(act, exp) + + +def test_ibw_(): + act = dumpibw("mac-version3Dependent.ibw") + exp = """ + {'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')}}} + """ + assert_equal_dump_no_whitespace_no_byte(act, exp) + + +def test_ibw_04(): + act = dumpibw("mac-version5.ibw") + exp = """ + {'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', + '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}}} + """ + assert_equal_dump_no_whitespace_no_byte(act, exp) + + +def test_ibw_05(): + act = dumpibw("mac-zeroPointWave.ibw") + exp = """ + {'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', + '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}}} + """ + assert_equal_dump_no_whitespace_no_byte(act, exp) + + +def test_ibw_06(): + act = dumpibw("win-double.ibw") + exp = """ + {'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')}}} + """ + assert_equal_dump_no_whitespace_no_byte(act, exp) + + +def test_ibw_07(): + act = dumpibw("win-textWave.ibw") + exp = """ + {'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', + '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}}} + """ + assert_equal_dump_no_whitespace_no_byte(act, exp) + + +def test_ibw_08(): + act = dumpibw("win-version2.ibw") + exp = """ + {'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')}}} + """ + assert_equal_dump_no_whitespace_no_byte(act, exp) + + +def test_ibw_09(): + act = dumpibw("win-version5.ibw") + exp = """ + {'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', + '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}}} + """ + assert_equal_dump_no_whitespace_no_byte(act, exp) + + +def test_ibw_10(): + act = dumpibw("win-zeroPointWave.ibw") + + exp = """ + {'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', + '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}}} + """ + assert_equal_dump_no_whitespace_no_byte(act, exp) diff --git a/test/test_pxp.py b/test/test_pxp.py new file mode 100644 index 0000000..95a663a --- /dev/null +++ b/test/test_pxp.py @@ -0,0 +1,433 @@ +import numpy as np + +from igor.packed import load as loadpxp + +from helper import data_dir + + +def tostr(data): + if isinstance(data, bytes): + data = data.decode("utf-8") + return data + + +def test_pxp(): + data = loadpxp(data_dir / "polar-graphs-demo.pxp") + records = data[0] + assert len(records) == 51 + + assert records[30].variables == { + "version": 1, + "variables": { + "var_header": {"numSysVars": 21, "numUserVars": 0, "numUserStrs": 0}, + "sysVars": { + "K0": 0.0, + "K1": 0.0, + "K2": 0.0, + "K3": 0.0, + "K4": 0.0, + "K5": 0.0, + "K6": 0.0, + "K7": 0.0, + "K8": 0.0, + "K9": 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, + "K20": 128.0, + }, + "userVars": {}, + "userStrs": {}, + }, + } + + wave = data[1]["root"] + wkeys = [tostr(st) for st in wave.keys()] + assert sorted(wkeys) == sorted( + [ + "K0", + "K1", + "K2", + "K3", + "K4", + "K5", + "K6", + "K7", + "K8", + "K9", + "K10", + "K11", + "K12", + "K13", + "K14", + "K15", + "K16", + "K17", + "K18", + "K19", + "K20", + "radiusData", + "angleData", + "W_plrX5", + "W_plrY5", + "angleQ1", + "radiusQ1", + "W_plrX6", + "W_plrY6", + "Packages", + ] + ) + + assert np.allclose( + records[32].wave["wave"]["wData"], + np.array( + [ + 0.3, + 0.5448544, + 0.77480197, + 0.9758435, + 1.1357394, + 1.2447554, + 1.2962544, + 1.287101, + 1.2178528, + 1.0927255, + 0.91933674, + 0.7082426, + 0.47229454, + 0.22585714, + -0.01606643, + -0.23874778, + -0.42862982, + -0.574153, + -0.6664573, + -0.6999235, + -0.6725141, + -0.5858976, + -0.44534767, + -0.25942117, + -0.03943586, + 0.20121357, + 0.44787762, + 0.6855388, + 0.8997279, + 1.0774051, + 1.2077546, + 1.2828392, + 1.2980883, + 1.2525737, + 1.1490659, + 0.99386656, + 0.7964253, + 0.5687607, + 0.32473388, + 0.07920124, + -0.15288824, + -0.35740662, + -0.5219018, + -0.636359, + -0.69381076, + -0.69075894, + -0.62739, + -0.5075599, + -0.3385666, + -0.13069656, + 0.10339352, + 0.34945396, + 0.5925036, + 0.8177455, + 1.0114669, + 1.1618733, + 1.2598093, + 1.2993116, + 1.277976, + 1.1971004, + 1.061609, + 0.8797508, + 0.6625979, + 0.4233691, + 0.17663053, + -0.06259823, + -0.2797519, + -0.46160996, + -0.597101, + -0.6779761, + -0.6993116, + -0.6598092, + -0.56187314, + -0.41146588, + -0.21774435, + 0.00749773, + 0.25054744, + 0.49660596, + 0.7306987, + 0.9385669, + 1.1075606, + 1.2273898, + 1.2907591, + 1.2938106, + 1.2363585, + 1.1219027, + 0.95740634, + 0.7528879, + 0.5207975, + 0.2752648, + 0.03123802, + -0.19642642, + -0.39386547, + -0.54906607, + -0.6525743, + -0.6980884, + -0.682839, + -0.607754, + -0.47740453, + -0.29972947, + -0.08553842, + 0.15212469, + 0.39878684, + 0.6394367, + 0.85942155, + 1.0453486, + 1.1858985, + 1.2725141, + 1.2999234, + 1.2664578, + 1.1741526, + 1.0286293, + 0.83874667, + 0.6160649, + 0.37414294, + 0.12770344, + -0.1082412, + -0.3193372, + -0.49272597, + -0.6178533, + -0.6871013, + -0.6962544, + -0.6447547, + -0.5357403, + -0.37584305, + -0.17479956, + 0.05514668, + 0.30000135, + ], + dtype=np.float32, + ), + ) + + assert np.allclose( + records[33].wave["wave"]["wData"], + np.array( + [ + 0.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, + 0.98947805, + 1.03895199, + 1.08842587, + 1.13789964, + 1.18737364, + 1.23684752, + 1.2863214, + 1.3357954, + 1.38526928, + 1.43474305, + 1.48421705, + 1.53369093, + 1.58316481, + 1.63263881, + 1.68211269, + 1.73158658, + 1.78106046, + 1.83053434, + 1.88000822, + 1.92948222, + 1.9789561, + 2.02842999, + 2.07790399, + 2.12737775, + 2.17685175, + 2.22632551, + 2.27579927, + 2.32527351, + 2.37474728, + 2.42422128, + 2.47369504, + 2.52316904, + 2.5726428, + 2.6221168, + 2.67159081, + 2.72106457, + 2.77053857, + 2.82001233, + 2.86948609, + 2.91896009, + 2.9684341, + 3.0179081, + 3.06738186, + 3.11685586, + 3.16632962, + 3.21580338, + 3.26527762, + 3.31475139, + 3.36422539, + 3.41369915, + 3.46317315, + 3.51264691, + 3.56212091, + 3.61159492, + 3.66106868, + 3.71054268, + 3.76001644, + 3.8094902, + 3.85896444, + 3.90843821, + 3.95791221, + 4.00738621, + 4.05685997, + 4.10633373, + 4.15580797, + 4.20528126, + 4.2547555, + 4.30422926, + 4.3537035, + 4.40317726, + 4.45265102, + 4.50212526, + 4.55159855, + 4.60107279, + 4.65054703, + 4.70002079, + 4.74949455, + 4.79896832, + 4.84844255, + 4.89791584, + 4.94739008, + 4.99686432, + 5.04633808, + 5.09581184, + 5.14528561, + 5.19475985, + 5.24423361, + 5.29370737, + 5.34318161, + 5.3926549, + 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=np.float32, + ), + ) + + assert np.allclose( + records[39].wave["wave"]["wData"], + np.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, + 17.70048141, + 17.79942513, + 18.36241531, + 19.38741684, + 20.41767311, + 21.02259827, + 21.09260368, + 20.4905529, + 18.95538521, + 16.9299469, + 15.94969368, + 17.14490509, + 19.78741264, + 22.33615875, + 23.96352196, + 24.04369545, + 21.92454147, + 18.79150391, + 17.77407646, + 20.32803917, + 24.37140465, + 27.24079132, + 28.40307808, + 28.67787933, + 28.70550728, + 28.50283432, + 27.68538666, + 26.36607552, + 25.73583984, + 26.78374672, + 28.8236084, + 30.36226463, + 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=np.float32, + ), + ) From 7505d972efa5d1f87927720f371230d8e6db67cc Mon Sep 17 00:00:00 2001 From: Ryuichi Arafune Date: Tue, 12 Sep 2023 19:33:28 +0900 Subject: [PATCH 04/16] =?UTF-8?q?=F0=9F=A7=BC=20correction(=F0=9F=93=9C=20?= =?UTF-8?q?stub):=20update=20type=20hints?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- igor/struct.py | 2 +- igor/struct.pyi | 36 +++++++++++++++++++++++------------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/igor/struct.py b/igor/struct.py index 2bd90ba..3b65bc4 100644 --- a/igor/struct.py +++ b/igor/struct.py @@ -15,7 +15,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with igor. If not, see . -# Memo Diffierence (small but significant) +# Memo Diffierence (small but significant) """Structure and Field classes for declaring structures diff --git a/igor/struct.pyi b/igor/struct.pyi index d8aedf0..e184da9 100644 --- a/igor/struct.pyi +++ b/igor/struct.pyi @@ -1,23 +1,26 @@ from __future__ import annotations + import struct -from _typeshed import Incomplete from collections.abc import Generator - from typing import BinaryIO -from collections.abc import Iterable + +import numpy as np +from _typeshed import Incomplete +from numpy.typing import NDArray from igor.binarywave import ( - DynamicStringIndicesDataField, + DynamicDataUnitsField, DynamicDependencyFormulaField, + DynamicDimensionUnitsField, + DynamicLabelsField, + DynamicStringIndicesDataField, DynamicWaveDataField1, DynamicWaveDataField5, DynamicWaveNoteField, NullStaticStringField, - DynamicDataUnitsField, - DynamicDimensionUnitsField, - DynamicLabelsField, ) -from ._typing import IBW, BYTEORDER + +from ._typing import BYTEORDER, IBW class Field: @@ -49,11 +52,16 @@ class Field: def indexes(self) -> Generator[int, None, None]: ... - def pack_data(self, data: bytes | None = ...) -> Generator[Incomplete, None, None]: + def pack_data( + self, + data: list[dict[str, complex | NDArray[np.complex_]]] + | dict[str, complex | NDArray[np.complex_]] + | None = ..., + ) -> Generator[Incomplete, None, None]: ... def pack_item( - self, item: Iterable | None = ... + self, item: Incomplete | None = ... ) -> Generator[Incomplete, None, None]: ... @@ -93,7 +101,9 @@ class Structure(struct.Struct): ] byte_order: BYTEORDER - def __init__(self, name: str, fields, byte_order: BYTEORDER = ...) -> None: + def __init__( + self, name: str, fields: list[Field], byte_order: BYTEORDER = ... + ) -> None: ... def setup(self) -> None: @@ -108,7 +118,7 @@ class Structure(struct.Struct): def sub_format(self) -> Generator[Incomplete, None, None]: ... - def pack(self, data: bytes): + def pack(self, data: dict): ... def pack_into(self, buffer, offset: int = ..., data: bytes = ...): @@ -135,7 +145,7 @@ class DebuggingStream: class DynamicStructure(Structure): - def pack(self, data: bytes) -> bytearray: + def pack(self, data: dict) -> bytearray: ... def pack_into(self, buffer, offset: int = ..., data: bytes = ...) -> None: From 9cd20765ed6afc8042587a20c499a06ba148afa2 Mon Sep 17 00:00:00 2001 From: Ryuichi Arafune Date: Fri, 6 Oct 2023 12:37:06 +0900 Subject: [PATCH 05/16] =?UTF-8?q?=F0=9F=8E=89=20=20bump=20up=20the=20versi?= =?UTF-8?q?on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- igor/__init__.py | 2 +- igor/igorpy.py | 2 +- igor/util.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/igor/__init__.py b/igor/__init__.py index a9e393d..91f27e1 100644 --- a/igor/__init__.py +++ b/igor/__init__.py @@ -19,7 +19,7 @@ "Interface for reading binary IGOR files." -__version__ = "0.3.1" +__version__ = "0.3.2" import logging diff --git a/igor/igorpy.py b/igor/igorpy.py index 593819d..944d7c3 100644 --- a/igor/igorpy.py +++ b/igor/igorpy.py @@ -39,7 +39,7 @@ from .record.variables import VariablesRecord -__version__ = "0.10" +__version__ = "0.3.2" ENCODING = locale.getpreferredencoding() or sys.getdefaultencoding() diff --git a/igor/util.py b/igor/util.py index d7d455a..f7cc01a 100644 --- a/igor/util.py +++ b/igor/util.py @@ -37,7 +37,7 @@ def _ord(byte): return ord(byte) -def hex_bytes(buffer, spaces: int = 0): +def hex_bytes(buffer, spaces: int | None = None): r"""Pretty-printing for binary buffers. >>> hex_bytes(b'\x00\x01\x02\x03\x04') @@ -52,7 +52,7 @@ def hex_bytes(buffer, spaces: int = 0): '000102 030405 06' """ hex_bytes = ["{:02x}".format(_ord(x)) for x in buffer] - if not spaces: + if spaces is None: return "".join(hex_bytes) elif spaces == 1: return " ".join(hex_bytes) From e3f6eb072f7254367c36c812f301ea228dce5b16 Mon Sep 17 00:00:00 2001 From: Ryuichi Arafune Date: Fri, 6 Oct 2023 13:39:28 +0900 Subject: [PATCH 06/16] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20=20add=20python=20>?= =?UTF-8?q?=203.7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setup.py | 86 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 39 deletions(-) diff --git a/setup.py b/setup.py index 0f3a04a..2ebe62c 100644 --- a/setup.py +++ b/setup.py @@ -24,44 +24,52 @@ from igor import __version__ -package_name = 'igor' +package_name = "igor" _this_dir = os.path.dirname(__file__) -setup(name=package_name, - version=__version__, - author='W. Trevor King', - author_email='wking@tremily.us', - maintainer='Conrad Stansbury', - maintainer_email='chstan@berkeley.edu', - url='https://github.com/chstan/igorpy', - download_url='https://github.com/chstan/igorpy/tarball/master', - license='GNU Lesser General Public License v3 or later (LGPLv3+)', - platforms=['all'], - description=__doc__, - long_description=open(os.path.join(_this_dir, 'README'), 'r').read(), - classifiers=[ - 'Development Status :: 3 - Alpha', - 'Environment :: Console', - 'Intended Audience :: Developers', - 'Intended Audience :: Science/Research', - 'Operating System :: OS Independent', - 'License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)', - 'Programming Language :: Python', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.2', - 'Programming Language :: Python :: 3.3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Topic :: Scientific/Engineering', - 'Topic :: Software Development :: Libraries :: Python Modules', - ], - packages=[ - 'igor', - 'igor.record', - ], - scripts=[ - 'bin/igorbinarywave.py', - 'bin/igorpackedexperiment.py', - ], - provides=['igor ({})'.format(__version__)], - ) +setup( + name=package_name, + version=__version__, + author="W. Trevor King", + author_email="wking@tremily.us", + maintainer="Conrad Stansbury", + maintainer_email="chstan@berkeley.edu", + url="https://github.com/chstan/igorpy", + download_url="https://github.com/chstan/igorpy/tarball/master", + license="GNU Lesser General Public License v3 or later (LGPLv3+)", + platforms=["all"], + description=__doc__, + long_description=open(os.path.join(_this_dir, "README"), "r").read(), + classifiers=[ + "Development Status :: 3 - Alpha", + "Environment :: Console", + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "Operating System :: OS Independent", + "License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)", + "Programming Language :: Python", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3.2", + "Programming Language :: Python :: 3.3", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Topic :: Scientific/Engineering", + "Topic :: Software Development :: Libraries :: Python Modules", + ], + packages=[ + "igor", + "igor.record", + ], + scripts=[ + "bin/igorbinarywave.py", + "bin/igorpackedexperiment.py", + ], + provides=["igor ({})".format(__version__)], +) From f798d72d1254312d01d2e23d2876326797149d2d Mon Sep 17 00:00:00 2001 From: Ryuichi Arafune Date: Fri, 6 Oct 2023 14:43:11 +0900 Subject: [PATCH 07/16] =?UTF-8?q?=E2=9C=A8=20=20add=20pyproject.toml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..32b479f --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,25 @@ +[project] +name = "igorpy" +version = "0.3.2" +description = "Add your description here" +authors = [ + { name = "W. Trevor King", email = "wking@tremily.us" }, + { name = "Conrad Stansbury", email = "chstan@berkely.edu" }, +] +maintainers = [ + { name = "Ryuichi Arafune", email = "ryuichi.arafune@gmail.com" }, +] +dependencies = ["numpy"] +readme = "README.md" +requires-python = ">= 3.10" + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.rye] +managed = true +dev-dependencies = ["pytest>=7.3.2"] + +[tool.hatch.metadata] +allow-direct-references = true From 8e0d5299f29ed574dd8c0a7500b208b2d0db1d8f Mon Sep 17 00:00:00 2001 From: Ryuichi Arafune Date: Fri, 6 Oct 2023 14:45:39 +0900 Subject: [PATCH 08/16] =?UTF-8?q?=F0=9F=94=A5=20=20typo=20fix=20in=20pypro?= =?UTF-8?q?ject.toml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 32b479f..5493042 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ maintainers = [ { name = "Ryuichi Arafune", email = "ryuichi.arafune@gmail.com" }, ] dependencies = ["numpy"] -readme = "README.md" +readme = "README" requires-python = ">= 3.10" [build-system] From df64823fff74d797c46922f04b5cf63b0e1d46d0 Mon Sep 17 00:00:00 2001 From: Ryuichi Arafune Date: Fri, 6 Oct 2023 14:47:27 +0900 Subject: [PATCH 09/16] =?UTF-8?q?=F0=9F=94=A5=20=20add=20"md"=20suffix=20i?= =?UTF-8?q?n=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README => README.md | 0 pyproject.toml | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename README => README.md (100%) diff --git a/README b/README.md similarity index 100% rename from README rename to README.md diff --git a/pyproject.toml b/pyproject.toml index 5493042..32b479f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ maintainers = [ { name = "Ryuichi Arafune", email = "ryuichi.arafune@gmail.com" }, ] dependencies = ["numpy"] -readme = "README" +readme = "README.md" requires-python = ">= 3.10" [build-system] From 2bd9c5dfe8af5140a407bb46063786d0f4dab1ae Mon Sep 17 00:00:00 2001 From: Ryuichi Arafune Date: Fri, 13 Oct 2023 22:22:34 +0900 Subject: [PATCH 10/16] =?UTF-8?q?=F0=9F=94=A7=20=20apply=20pyupgrade=20(to?= =?UTF-8?q?=203.8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- igor/_typing.py | 2 + igor/binarywave.py | 9 ++-- igor/igorpy.py | 73 ++++++++++++++++---------------- igor/packed.py | 6 +-- igor/record/base.py | 6 +-- igor/record/variables.py | 8 ++-- igor/record/wave.py | 2 +- igor/script.py | 9 ++-- igor/struct.py | 89 ++++++++++++++++++---------------------- igor/util.py | 9 ++-- pyproject.toml | 2 +- 11 files changed, 101 insertions(+), 114 deletions(-) diff --git a/igor/_typing.py b/igor/_typing.py index fc4a0ef..3526ed5 100644 --- a/igor/_typing.py +++ b/igor/_typing.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import numpy as np from typing import TypedDict, TypeAlias, Literal from numpy.typing import NDArray diff --git a/igor/binarywave.py b/igor/binarywave.py index 5f1d249..8bf4d5d 100644 --- a/igor/binarywave.py +++ b/igor/binarywave.py @@ -27,7 +27,6 @@ # 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 numpy as np @@ -62,7 +61,7 @@ class StaticStringField(DynamicField): def __init__(self, *args, **kwargs) -> None: if "array" not in kwargs: kwargs["array"] = True - super(StaticStringField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def post_unpack(self, parents, data): wave_structure = parents[-1] @@ -597,7 +596,7 @@ def unpack(self, stream): order="F", ) except: - LOG.error("could not reshape data from {} to {}".format(self.shape, data_b)) + LOG.error(f"could not reshape data from {self.shape} to {data_b}") raise return data @@ -782,7 +781,7 @@ def post_unpack(self, parents, data): wdata = wdata.reshape(shape) except ValueError: LOG.error( - "could not reshape strings from {} to {}".format(shape, wdata.shape) + f"could not reshape strings from {shape} to {wdata.shape}" ) raise wave_data["wData"] = wdata @@ -817,7 +816,7 @@ def post_unpack(self, parents, data): elif version == 5: wave_structure.fields[-1].format = Wave5 elif not need_to_reorder_bytes: - raise ValueError("invalid binary wave version: {}".format(version)) + raise ValueError(f"invalid binary wave version: {version}") if wave_structure.fields[-1].format != old_format: LOG.debug( diff --git a/igor/igorpy.py b/igor/igorpy.py index 944d7c3..6a1e374 100644 --- a/igor/igorpy.py +++ b/igor/igorpy.py @@ -1,7 +1,7 @@ # This program is in the public domain """`igor.py` compatibility layer on top of the `igor` package. -igor.load('filename') or igor.loads('data') loads the content of an igore file +igor.load('filename') or igor.loads('data') loads the content of an igor file into memory as a folder structure. Returns the root folder. @@ -17,7 +17,6 @@ # Memo no related file in igor2 -from __future__ import absolute_import import io import locale import re @@ -43,37 +42,35 @@ ENCODING = locale.getpreferredencoding() or sys.getdefaultencoding() -PYKEYWORDS = set( - ( - "and", - "as", - "assert", - "break", - "class", - "continue", - "def", - "elif", - "else", - "except", - "exec", - "finally", - "for", - "global", - "if", - "import", - "in", - "is", - "lambda", - "or", - "pass", - "print", - "raise", - "return", - "try", - "with", - "yield", - ) -) +PYKEYWORDS = { + "and", + "as", + "assert", + "break", + "class", + "continue", + "def", + "elif", + "else", + "except", + "exec", + "finally", + "for", + "global", + "if", + "import", + "in", + "is", + "lambda", + "or", + "pass", + "print", + "raise", + "return", + "try", + "with", + "yield", +} PYID = re.compile(r"^[^\d\W]\w*$", re.UNICODE) @@ -82,7 +79,7 @@ def valid_identifier(s): return PYID.match(s) and s not in PYKEYWORDS -class IgorObject(object): +class IgorObject: """Parent class for all objects the parser can return""" pass @@ -168,7 +165,7 @@ def format(self, indent=0): type, size = "text", "%d" % len(self.data) else: type, size = "data", "x".join(str(d) for d in self.data.shape) - return " " * indent + "%s %s (%s)" % (self.name, type, size) + return " " * indent + "{} {} ({})".format(self.name, type, size) def __array__(self): return self.data @@ -301,9 +298,9 @@ def load(filename, **kwargs): ) except ValueError as e: if e.args[0].startswith("not enough data for the next record header"): - raise IOError("invalid record header; bad pxp file?") + raise OSError("invalid record header; bad pxp file?") elif e.args[0].startswith("not enough data for the next record"): - raise IOError("final record too long; bad pxp file?") + raise OSError("final record too long; bad pxp file?") raise return _convert(packed_experiment, **kwargs) @@ -346,5 +343,5 @@ def _convert(packed_experiment, ignore_unknown=True): else: stack[-1].append(r) if len(stack) != 1: - raise IOError("FolderStart records do not match FolderEnd records") + raise OSError("FolderStart records do not match FolderEnd records") return stack[0] diff --git a/igor/packed.py b/igor/packed.py index 3c9f995..0606086 100644 --- a/igor/packed.py +++ b/igor/packed.py @@ -70,7 +70,7 @@ def load(filename, *, strict=True, ignore_unknown=True, initial_byte_order="="): Probably better to actually infer the initial_byte_order, as can be done from the header. For now though we will let the user deal with this. """ - LOG.debug("loading a packed experiment file from {}".format(filename)) + LOG.debug(f"loading a packed experiment file from {filename}") records = [] if hasattr(filename, "read"): f = filename # filename is actually a stream object @@ -124,7 +124,7 @@ def load(filename, *, strict=True, ignore_unknown=True, initial_byte_order="="): raise KeyError("unkwon 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)) + LOG.debug(f"finished loading {len(records)} records from {filename}") if not hasattr(filename, "read"): f.close() @@ -145,7 +145,7 @@ def _build_filesystem(records): folder end record.""" # From the Igor Manual, chapter 2, section 8, page II-123 # http://www.wavemetrics.net/doc/igorman/II-08%20Data%20Folders.pdf - """Like the Macintosh file system, Igor Pro's data folders use the + r"""Like the Macintosh file system, Igor Pro's data folders use the colon character (:) to separate components of a path to an object. This is analogous to Unix which uses / and Windows which uses \. (Reminder: Igor's data folders exist wholly in memory diff --git a/igor/record/base.py b/igor/record/base.py index e194634..e875fc7 100644 --- a/igor/record/base.py +++ b/igor/record/base.py @@ -19,7 +19,7 @@ # Memo No diff with igor2 -class Record(object): +class Record: def __init__(self, header, data, byte_order=None): self.header = header self.data = data @@ -29,7 +29,7 @@ def __str__(self): return self.__repr__() def __repr__(self): - return "<{} {}>".format(self.__class__.__name__, id(self)) + return f"<{self.__class__.__name__} {id(self)}>" class UnknownRecord(Record): @@ -45,6 +45,6 @@ class UnusedRecord(Record): class TextRecord(Record): def __init__(self, *args, **kwargs): - super(TextRecord, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.text = bytes(self.data).replace(b"\r\n", b"\n").replace(b"\r", b"\n") self.null_terminated_text = self.text.split(b"\x00", 1)[0] diff --git a/igor/record/variables.py b/igor/record/variables.py index d7822fe..015763a 100644 --- a/igor/record/variables.py +++ b/igor/record/variables.py @@ -64,7 +64,7 @@ class DynamicVarDataField(DynamicField): def __init__(self, *args, **kwargs): if "array" not in kwargs: kwargs["array"] = True - super(DynamicVarDataField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def pre_pack(self, parents, data): raise NotImplementedError() @@ -85,7 +85,7 @@ def _normalize_item(self, index, value): class DynamicSysVarField(DynamicVarDataField): def _normalize_item(self, index, value): - name = "K{}".format(index) + name = f"K{index}" return (name, value) @@ -331,7 +331,7 @@ def post_unpack(self, parents, data): elif version == 2: variables_structure.fields[-1].format = Variables2 elif not need_to_reorder_bytes: - raise ValueError("invalid variables record version: {}".format(version)) + raise ValueError(f"invalid variables record version: {version}") if variables_structure.fields[-1].format != old_format: LOG.debug( @@ -358,7 +358,7 @@ def post_unpack(self, parents, data): class VariablesRecord(Record): def __init__(self, *args, **kwargs): - super(VariablesRecord, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) # self.header['version'] # record version always 0? VariablesRecordStructure.byte_order = "=" VariablesRecordStructure.setup() diff --git a/igor/record/wave.py b/igor/record/wave.py index 92ad78f..13858dd 100644 --- a/igor/record/wave.py +++ b/igor/record/wave.py @@ -25,7 +25,7 @@ class WaveRecord(Record): def __init__(self, *args, **kwargs): - super(WaveRecord, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.wave = loadibw(BytesIO(bytes(self.data))) def __str__(self): diff --git a/igor/script.py b/igor/script.py index 8beaa7c..dc58156 100644 --- a/igor/script.py +++ b/igor/script.py @@ -20,7 +20,6 @@ "Common code for scripts distributed with the `igor` package." -from __future__ import absolute_import import argparse import logging import sys @@ -31,20 +30,20 @@ from . import LOG -class Script(object): +class Script: log_levels = [logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG] def __init__(self, description=None, filetype="IGOR Binary Wave (.ibw) file"): self.parser = argparse.ArgumentParser(description=description) self.parser.add_argument( - "--version", action="version", version="%(prog)s {}".format(__version__) + "--version", action="version", version=f"%(prog)s {__version__}" ) self.parser.add_argument( "-f", "--infile", metavar="FILE", default="-", - help="input {}".format(filetype), + help=f"input {filetype}", ) self.parser.add_argument( "-o", "--outfile", metavar="FILE", default="-", help="file for ASCII output" @@ -87,7 +86,7 @@ def plot_wave(self, args, wave, title=None): try: axes.plot(wave["wave"]["wData"], "r.") except ValueError as error: - LOG.error("error plotting {}: {}".format(title, error)) + LOG.error(f"error plotting {title}: {error}") pass self._num_plots += 1 diff --git a/igor/struct.py b/igor/struct.py index 3b65bc4..cf769e8 100644 --- a/igor/struct.py +++ b/igor/struct.py @@ -25,7 +25,6 @@ with each field in a hierarchy of Python dictionaries. """ from __future__ import annotations -from __future__ import absolute_import import io import logging import pprint @@ -35,7 +34,7 @@ from . import LOG -class Field(object): +class Field: """Represent a Structure field. The format argument can be a format character from the ``struct`` @@ -167,7 +166,7 @@ def setup(self): Use this method to recalculate dynamic properties after changing the basic properties set during initialization. """ - LOG.debug("setup {}".format(self)) + LOG.debug(f"setup {self}") self.item_count = np.prod(self.count) # number of item repeats if not self.array and self.item_count != 1: raise ValueError( @@ -187,7 +186,7 @@ def __str__(self): return self.__repr__() def __repr__(self): - return "<{} {} {}>".format(self.__class__.__name__, self.name, id(self)) + return f"<{self.__class__.__name__} {self.name} {id(self)}>" def indexes(self): """Iterate through indexes to a possibly multi-dimensional array""" @@ -218,8 +217,7 @@ def pack_data(self, data=None): items = 0 for item in data.flat: items += 1 - for arg in self.pack_item(item): - yield arg + yield from self.pack_item(item) if items < self.item_count: raise NotADirectoryError("Very bad state") """ @@ -239,38 +237,35 @@ def pack_data(self, data=None): item = item[i] except IndexError: item = None - for arg in self.pack_item(item): - yield arg + yield from self.pack_item(item) else: - for arg in self.pack_item(data): - yield arg + yield from self.pack_item(data) def pack_item(self, item=None): """Linearize a single count of the field's data to a flat iterable""" if isinstance(self.format, Structure): - for i in self.format._pack_item(item): - yield i + yield from self.format._pack_item(item) elif item is None: if self.default is None: - raise ValueError("no default for {}".format(self)) + raise ValueError(f"no default for {self}") yield self.default else: yield item def unpack_data(self, data): """Inverse of .pack_data""" - LOG.debug("unpack {} for {} {}".format(data, self, self.format)) + LOG.debug(f"unpack {data} for {self} {self.format}") iterator = iter(data) try: items = [next(iterator) for i in range(self.arg_count)] except StopIteration: - raise ValueError("not enough data to unpack {}".format(self)) + raise ValueError(f"not enough data to unpack {self}") try: next(iterator) except StopIteration: pass else: - raise ValueError("too much data to unpack {}".format(self)) + raise ValueError(f"too much data to unpack {self}") if isinstance(self.format, Structure): # break into per-structure clumps s = self.structure_count @@ -295,7 +290,7 @@ def unpack_data(self, data): else: unpacked = np.array(unpacked) LOG.debug( - "reshape {} data from {} to {}".format(self, unpacked.shape, count) + f"reshape {self} data from {unpacked.shape} to {count}" ) unpacked = unpacked.reshape(count) return unpacked @@ -498,7 +493,7 @@ def __str__(self): return self.name def __repr__(self): - return "<{} {} {}>".format(self.__class__.__name__, self.name, id(self)) + return f"<{self.__class__.__name__} {self.name} {id(self)}>" def setup(self): """Setup any dynamic properties of a structure. @@ -506,13 +501,13 @@ def setup(self): Use this method to recalculate dynamic properities after changing the basic properties set during initialization. """ - LOG.debug("setup {!r}".format(self)) + LOG.debug(f"setup {self!r}") 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.""" - LOG.debug("set byte order for {!r} to {}".format(self, byte_order)) + LOG.debug(f"set byte order for {self!r} to {byte_order}") self.byte_order = byte_order for field in self.fields: if isinstance(field.format, Structure): @@ -524,20 +519,19 @@ def get_format(self) -> str: # Convert P to I for ILP32 compatibility when running on a LP64. format = format.replace("P", "I") try: - super(Structure, self).__init__(format=format) + super().__init__(format=format) except struct.error as e: raise ValueError((e, format)) return format def sub_format(self): - LOG.debug("calculate sub-format for {!r}".format(self)) + LOG.debug(f"calculate sub-format for {self!r}") 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 + yield from field_format def _pack_item(self, item: dict | None = None): """Linearize a single count of the structure's data to a flat iterable""" @@ -550,8 +544,7 @@ def _pack_item(self, item: dict | None = None): raise ValueError((f.name, item)) except KeyError: data = None - for arg in f.pack_data(data): - yield arg + yield from f.pack_data(data) def _unpack_item(self, args): """Inverse of ._unpack_item""" @@ -561,20 +554,20 @@ def _unpack_item(self, args): try: items = [next(iterator) for i in range(f.arg_count)] except StopIteration: - raise ValueError("not enough data to unpack {}.{}".format(self, f)) + raise ValueError(f"not enough data to unpack {self}.{f}") data[f.name] = f.unpack_data(items) try: next(iterator) except StopIteration: pass else: - raise ValueError("too much data to unpack {}".format(self)) + raise ValueError(f"too much data to unpack {self}") return data def pack(self, data): args = list(self._pack_item(data)) try: - return super(Structure, self).pack(*args) + return super().pack(*args) except: raise ValueError(self.format) @@ -582,10 +575,10 @@ def pack_into( self, buffer, offset=0, data={} ): # check !! should data:dict|None = None? args = list(self._pack_item(data)) - return super(Structure, self).pack_into(buffer, offset, *args) + return super().pack_into(buffer, offset, *args) def unpack(self, *args, **kwargs): - args = super(Structure, self).unpack(*args, **kwargs) + args = super().unpack(*args, **kwargs) return self._unpack_item(args) def unpack_from(self, buffer, offset=0, *args, **kwargs): @@ -594,21 +587,21 @@ def unpack_from(self, buffer, offset=0, *args, **kwargs): buffer, self, len(buffer), offset, self.format, self.size ) ) - args = super(Structure, self).unpack_from(buffer, offset, *args, **kwargs) + args = super().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): +class DebuggingStream: 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) + f"read {size} from {self.stream}: ({len(data)}) {data!r}" ) return data @@ -711,21 +704,21 @@ def _pre_pack(self, parents: list | None = None, data=None): parents = parents + [self] for f in self.fields: if hasattr(f, "pre_pack"): - LOG.debug("pre-pack {}".format(f)) + LOG.debug(f"pre-pack {f}") f.pre_pack(parents=parents, data=data) if isinstance(f.format, DynamicStructure): - LOG.debug("pre-pack {!r}".format(f.format)) + LOG.debug(f"pre-pack {f.format!r}") f._pre_pack(parents=parents, data=data) def pack(self, data): self._pre_pack(data=data) self.setup() - return super(DynamicStructure, self).pack(data) + return super().pack(data) def pack_into(self, buffer, offset=0, data={}): self._pre_pack(data=data) self.setup() - return super(DynamicStructure, self).pack_into( + return super().pack_into( buffer=buffer, offset=offset, data=data ) @@ -746,13 +739,13 @@ def unpack_stream(self, stream, parents=None, data: dict | None = None, d=None): ) ) if LOG.level <= logging.DEBUG: - LOG.debug("data:\n{}".format(pprint.pformat(data))) + LOG.debug(f"data:\n{pprint.pformat(data)}") if hasattr(f, "pre_unpack"): - LOG.debug("pre-unpack {}".format(f)) + LOG.debug(f"pre-unpack {f}") f.pre_unpack(parents=parents, data=data) if hasattr(f, "unpack"): # override default unpacking - LOG.debug("override unpack for {}".format(f)) + LOG.debug(f"override unpack for {f}") d[f.name] = f.unpack(stream) continue @@ -777,7 +770,7 @@ def unpack_stream(self, stream, parents=None, data: dict | None = None, d=None): stream, parents=parents, data=data, d=d[f.name] ) if hasattr(f, "post_unpack"): - LOG.debug("post-unpack {}".format(f)) + LOG.debug(f"post-unpack {f}") repeat = f.post_unpack(parents=parents, data=data) if repeat: raise NotImplementedError( @@ -786,7 +779,7 @@ def unpack_stream(self, stream, parents=None, data: dict | None = None, d=None): continue if isinstance(f.format, Structure): LOG.debug( - "parsing {} bytes for {}".format(f.format.size, f.format.format) + f"parsing {f.format.size} bytes for {f.format.format}" ) bs = [stream.read(f.format.size) for i in range(f.item_count)] @@ -807,10 +800,10 @@ def unpack(): size = struct.calcsize(field_format) except struct.error as e: LOG.error(e) - LOG.error("{}.{}: {}".format(self, f, field_format)) + LOG.error(f"{self}.{f}: {field_format}") raise LOG.debug( - "parsing {} bytes for preliminary {}".format(size, field_format) + f"parsing {size} bytes for preliminary {field_format}" ) raw = stream.read(size) if len(raw) < size: @@ -823,7 +816,7 @@ def unpack(): 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)) + LOG.debug(f"parse previous bytes using {field_format}") items = struct.Struct(field_format).unpack(raw) return f.unpack_data(items) @@ -832,12 +825,12 @@ def unpack(): while repeat: d[f.name] = unpack() if hasattr(f, "post_unpack"): - LOG.debug("post-unpack {}".format(f)) + LOG.debug(f"post-unpack {f}") repeat = f.post_unpack(parents=parents, data=data) else: repeat = False if repeat: - LOG.debug("repeat unpack for {}".format(f)) + LOG.debug(f"repeat unpack for {f}") return data diff --git a/igor/util.py b/igor/util.py index f7cc01a..764f8a3 100644 --- a/igor/util.py +++ b/igor/util.py @@ -31,10 +31,7 @@ def _ord(byte): >>> [_ord(b) for b in buffer] [0, 1, 2] """ - if sys.version_info >= (3,): - return byte - else: - return ord(byte) + return byte def hex_bytes(buffer, spaces: int | None = None): @@ -51,7 +48,7 @@ def hex_bytes(buffer, spaces: int | None = None): >>> hex_bytes(b'\x00\x01\x02\x03\x04\x05\x06', spaces=3) '000102 030405 06' """ - hex_bytes = ["{:02x}".format(_ord(x)) for x in buffer] + hex_bytes = [f"{_ord(x):02x}" for x in buffer] if spaces is None: return "".join(hex_bytes) elif spaces == 1: @@ -83,7 +80,7 @@ def assert_null(buffer, strict=True): raise ValueError(hex_string) else: sys.stderr.write( - "warning: post-data padding not zero: {}\n".format(hex_string) + f"warning: post-data padding not zero: {hex_string}\n" ) diff --git a/pyproject.toml b/pyproject.toml index 32b479f..b25df4e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ maintainers = [ ] dependencies = ["numpy"] readme = "README.md" -requires-python = ">= 3.10" +requires-python = ">= 3.8" [build-system] requires = ["hatchling"] From 933d34833f4a77e9ee819b406bb8b573a89ffcbf Mon Sep 17 00:00:00 2001 From: Ryuichi Arafune Date: Fri, 13 Oct 2023 22:30:43 +0900 Subject: [PATCH 11/16] =?UTF-8?q?=F0=9F=92=AC=20=20move=20type=20hints=20t?= =?UTF-8?q?o=20stub?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- igor/util.py | 8 +++----- igor/util.pyi | 24 +++++++++++++++++++----- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/igor/util.py b/igor/util.py index 764f8a3..8dbdba4 100644 --- a/igor/util.py +++ b/igor/util.py @@ -18,7 +18,7 @@ # Memo: No essential diff with igor2 "Utility functions for handling buffers" - +from __future__ import annotations import sys as sys import numpy as np @@ -34,7 +34,7 @@ def _ord(byte): return byte -def hex_bytes(buffer, spaces: int | None = None): +def hex_bytes(buffer, spaces=None): r"""Pretty-printing for binary buffers. >>> hex_bytes(b'\x00\x01\x02\x03\x04') @@ -79,9 +79,7 @@ def assert_null(buffer, strict=True): if strict: raise ValueError(hex_string) else: - sys.stderr.write( - f"warning: post-data padding not zero: {hex_string}\n" - ) + sys.stderr.write(f"warning: post-data padding not zero: {hex_string}\n") # From ReadWave.c diff --git a/igor/util.pyi b/igor/util.pyi index f476f12..1b82e10 100644 --- a/igor/util.pyi +++ b/igor/util.pyi @@ -2,10 +2,24 @@ from __future__ import annotations from _typeshed import Incomplete from ._typing import BYTEORDER -def hex_bytes(buffer: Incomplete, spaces: int = ...) -> str: ... -def assert_null(buffer: Incomplete, strict: bool = ...) -> None: ... -def byte_order(needToReorderBytes: bool) -> BYTEORDER: ... -def need_to_reorder_bytes(version: int) -> bool: ... + +def hex_bytes(buffer: Incomplete, spaces: int | None = ...) -> str: + ... + + +def assert_null(buffer: Incomplete, strict: bool = ...) -> None: + ... + + +def byte_order(needToReorderBytes: bool) -> BYTEORDER: + ... + + +def need_to_reorder_bytes(version: int) -> bool: + ... + + def checksum( buffer: Incomplete, byte_order: BYTEORDER, oldcksum: int, numbytes: int -) -> int: ... +) -> int: + ... From 458ed6f2df394539e3775c6b927fc23d1d0b7834 Mon Sep 17 00:00:00 2001 From: Ryuichi Arafune Date: Mon, 16 Oct 2023 11:29:52 +0900 Subject: [PATCH 12/16] =?UTF-8?q?=F0=9F=92=AC=20=20update=20type=20hints?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- igor/__init__.py | 1 + igor/_typing.py | 1 - igor/binarywave.py | 6 +-- igor/binarywave.pyi | 90 ++++++++++++++++++++++++++++++++++----------- igor/igorpy.py | 4 +- igor/struct.py | 21 +++-------- pyproject.toml | 4 ++ 7 files changed, 83 insertions(+), 44 deletions(-) diff --git a/igor/__init__.py b/igor/__init__.py index 91f27e1..e655275 100644 --- a/igor/__init__.py +++ b/igor/__init__.py @@ -21,6 +21,7 @@ __version__ = "0.3.2" +__all__ = ("__version__",) import logging diff --git a/igor/_typing.py b/igor/_typing.py index 3526ed5..4ff0435 100644 --- a/igor/_typing.py +++ b/igor/_typing.py @@ -12,7 +12,6 @@ from .record.history import HistoryRecord from .record.history import GetHistoryRecord from .record.history import RecreationRecord -from .record.packedfile import PackedFileRecord from .record.procedure import ProcedureRecord from .record.wave import WaveRecord from .record.variables import VariablesRecord diff --git a/igor/binarywave.py b/igor/binarywave.py index 8bf4d5d..8caff98 100644 --- a/igor/binarywave.py +++ b/igor/binarywave.py @@ -58,7 +58,7 @@ class StaticStringField(DynamicField): _null_terminated = False _array_size_field = None - def __init__(self, *args, **kwargs) -> None: + def __init__(self, *args, **kwargs): if "array" not in kwargs: kwargs["array"] = True super().__init__(*args, **kwargs) @@ -780,9 +780,7 @@ def post_unpack(self, parents, data): try: wdata = wdata.reshape(shape) except ValueError: - LOG.error( - f"could not reshape strings from {shape} to {wdata.shape}" - ) + LOG.error(f"could not reshape strings from {shape} to {wdata.shape}") raise wave_data["wData"] = wdata diff --git a/igor/binarywave.pyi b/igor/binarywave.pyi index 80bc101..ccfade9 100644 --- a/igor/binarywave.pyi +++ b/igor/binarywave.pyi @@ -1,5 +1,5 @@ from __future__ import annotations -from typing import BinaryIO +from typing import BinaryIO, NoReturn from . import LOG as LOG from .struct import DynamicField, DynamicStructure, Structure from _typeshed import Incomplete @@ -14,13 +14,20 @@ complexUInt8: DTypeLike complexUInt16: DTypeLike complexUInt32: DTypeLike + class StaticStringField(DynamicField): def __init__( self, *args: str | Structure | int, **kwargs: str | int | bool - ) -> None: ... - def post_unpack(self, parents: type, data: bytes) -> None: ... + ) -> None: + ... + + def post_unpack(self, parents: type, data: bytes) -> None: + ... + + +class NullStaticStringField(StaticStringField): + ... -class NullStaticStringField(StaticStringField): ... TYPE_TABLE: dict[int, DTypeLike] MAXDIMS: int @@ -34,48 +41,82 @@ MAX_UNIT_CHARS: int WaveHeader2: DynamicStructure WaveHeader5: DynamicStructure + class DynamicWaveDataField1(DynamicField): - def pre_pack(self, parents: type, data: bytes) -> None: ... + def pre_pack(self, parents: type, data: bytes) -> None: + ... count: Incomplete data_size: Incomplete shape: Incomplete dtype: Incomplete - def pre_unpack(self, parents: type, data: bytes) -> None: ... - def unpack(self, stream: BinaryIO): ... + def pre_unpack(self, parents: type, data: bytes) -> None: + ... + + def unpack(self, stream: BinaryIO): + ... + + +class DynamicWaveDataField5(DynamicWaveDataField1): + ... -class DynamicWaveDataField5(DynamicWaveDataField1): ... class DynamicStringField(StaticStringField): counts: Incomplete count: Incomplete - def pre_unpack(self, parents: type, data: bytes) -> None: ... + def pre_unpack(self, parents: type, data: bytes) -> None: + ... + + +class DynamicWaveNoteField(DynamicStringField): + ... + + +class DynamicDependencyFormulaField(DynamicStringField): + ... + + +class DynamicDataUnitsField(DynamicStringField): + ... + + +class DynamicDimensionUnitsField(DynamicStringField): + ... -class DynamicWaveNoteField(DynamicStringField): ... -class DynamicDependencyFormulaField(DynamicStringField): ... -class DynamicDataUnitsField(DynamicStringField): ... -class DynamicDimensionUnitsField(DynamicStringField): ... class DynamicLabelsField(DynamicStringField): - def post_unpack(self, parents: type, data: bytes) -> None: ... + def post_unpack(self, parents: type, data: bytes) -> None: + ... + class DynamicStringIndicesDataField(DynamicField): - def pre_pack(self, parents: type, data: bytes) -> None: ... + def pre_pack(self, parents: type, data: bytes) -> None: + ... string_indices_size: Incomplete count: Incomplete - def pre_unpack(self, parents: type, data: bytes) -> None: ... - def post_unpack(self, parents: type, data: bytes) -> None: ... + def pre_unpack(self, parents: type, data: bytes) -> None: + ... + + def post_unpack(self, parents: type, data: bytes) -> None: + ... + class DynamicVersionField(DynamicField): - def pre_pack(self, parents: type, byte_order: BYTEORDER) -> None: ... - def post_unpack(self, parents: type, data: bytes): ... + def pre_pack(self, parents: type, byte_order: BYTEORDER) -> NoReturn: + ... + + def post_unpack(self, parents: type, data: bytes): + ... + class DynamicWaveField(DynamicField): - def post_unpack(self, parents: type, data: bytes) -> None: ... + def post_unpack(self, parents: type, data: bytes) -> None: + ... + Wave1: DynamicStructure Wave2: DynamicStructure @@ -83,5 +124,10 @@ Wave3: DynamicStructure Wave5: DynamicStructure Wave: DynamicStructure -def load(filename: str | Path) -> IBW: ... -def save(filename: str) -> None: ... + +def load(filename: str | Path) -> IBW: + ... + + +def save(filename: str) -> None: + ... diff --git a/igor/igorpy.py b/igor/igorpy.py index 6a1e374..c64e4d6 100644 --- a/igor/igorpy.py +++ b/igor/igorpy.py @@ -25,7 +25,7 @@ import numpy as np from .binarywave import MAXDIMS -from .packed import load as _load +from .packed import load as packed_load from .record.base import UnknownRecord from .record.folder import FolderStartRecord from .record.folder import FolderEndRecord @@ -293,7 +293,7 @@ def loads(s, **kwargs): def load(filename, **kwargs): """Load an igor file""" try: - packed_experiment = _load( + packed_experiment = packed_load( filename, initial_byte_order=kwargs.pop("initial_byte_order", "=") ) except ValueError as e: diff --git a/igor/struct.py b/igor/struct.py index cf769e8..7512da0 100644 --- a/igor/struct.py +++ b/igor/struct.py @@ -31,6 +31,7 @@ import struct import numpy as np +from . import __version__ from . import LOG @@ -289,9 +290,7 @@ def unpack_data(self, data): raise NotImplementedError("reshape Structure field") else: unpacked = np.array(unpacked) - LOG.debug( - f"reshape {self} data from {unpacked.shape} to {count}" - ) + LOG.debug(f"reshape {self} data from {unpacked.shape} to {count}") unpacked = unpacked.reshape(count) return unpacked @@ -600,9 +599,7 @@ def __init__(self, stream): def read(self, size): data = self.stream.read(size) - LOG.debug( - f"read {size} from {self.stream}: ({len(data)}) {data!r}" - ) + LOG.debug(f"read {size} from {self.stream}: ({len(data)}) {data!r}") return data @@ -718,9 +715,7 @@ def pack(self, data): def pack_into(self, buffer, offset=0, data={}): self._pre_pack(data=data) self.setup() - return super().pack_into( - buffer=buffer, offset=offset, data=data - ) + return super().pack_into(buffer=buffer, offset=offset, data=data) def unpack_stream(self, stream, parents=None, data: dict | None = None, d=None): # `d` is the working data directory @@ -778,9 +773,7 @@ def unpack_stream(self, stream, parents=None, data: dict | None = None, d=None): ) continue if isinstance(f.format, Structure): - LOG.debug( - f"parsing {f.format.size} bytes for {f.format.format}" - ) + LOG.debug(f"parsing {f.format.size} bytes for {f.format.format}") bs = [stream.read(f.format.size) for i in range(f.item_count)] def unpack(): @@ -802,9 +795,7 @@ def unpack(): LOG.error(e) LOG.error(f"{self}.{f}: {field_format}") raise - LOG.debug( - f"parsing {size} bytes for preliminary {field_format}" - ) + LOG.debug(f"parsing {size} bytes for preliminary {field_format}") raw = stream.read(size) if len(raw) < size: raise ValueError( diff --git a/pyproject.toml b/pyproject.toml index b25df4e..e05a2dc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,3 +23,7 @@ dev-dependencies = ["pytest>=7.3.2"] [tool.hatch.metadata] allow-direct-references = true + +[tool.mypy] +ignore_missing_imports = true +enable_incomplete_feature = ["Unpack"] From 29a91c804b8e53841f5682a1d8560f7bc0fe2a1d Mon Sep 17 00:00:00 2001 From: Ryuichi Arafune Date: Mon, 16 Oct 2023 17:37:23 +0900 Subject: [PATCH 13/16] =?UTF-8?q?=F0=9F=94=A7=20=20update=20.gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 8d35cb3..89fdf58 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ __pycache__ -*.pyc +*.py[cod] + +dist/ From fc4abd597cdf02c07a0dfd3bba0511261a39f52c Mon Sep 17 00:00:00 2001 From: Ryuichi Arafune Date: Sun, 11 Feb 2024 19:38:38 +0900 Subject: [PATCH 14/16] =?UTF-8?q?=F0=9F=92=A5=20=20Restructuring=20the=20p?= =?UTF-8?q?ackage=20layout?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +++ setup.py => legacy_files/setup.py | 0 pyproject.toml | 10 ++++++---- {igor => src/igor}/__init__.py | 0 {igor => src/igor}/__init__.pyi | 0 {igor => src/igor}/_typing.py | 0 {igor => src/igor}/binarywave.py | 0 {igor => src/igor}/binarywave.pyi | 0 {igor => src/igor}/igorpy.py | 0 {igor => src/igor}/igorpy.pyi | 0 {igor => src/igor}/packed.py | 0 {igor => src/igor}/packed.pyi | 0 {igor => src/igor}/record/__init__.py | 0 {igor => src/igor}/record/__init__.pyi | 0 {igor => src/igor}/record/base.py | 0 {igor => src/igor}/record/base.pyi | 0 {igor => src/igor}/record/folder.py | 0 {igor => src/igor}/record/folder.pyi | 0 {igor => src/igor}/record/history.py | 0 {igor => src/igor}/record/history.pyi | 0 {igor => src/igor}/record/packedfile.py | 0 {igor => src/igor}/record/packedfile.pyi | 0 {igor => src/igor}/record/procedure.py | 0 {igor => src/igor}/record/procedure.pyi | 0 {igor => src/igor}/record/variables.py | 0 {igor => src/igor}/record/variables.pyi | 0 {igor => src/igor}/record/wave.py | 0 {igor => src/igor}/record/wave.pyi | 0 {igor => src/igor}/script.py | 0 {igor => src/igor}/script.pyi | 0 {igor => src/igor}/struct.py | 0 {igor => src/igor}/struct.pyi | 0 {igor => src/igor}/util.py | 0 {igor => src/igor}/util.pyi | 0 test/data/ID_003.ibw | Bin 0 -> 437315 bytes 35 files changed, 9 insertions(+), 4 deletions(-) rename setup.py => legacy_files/setup.py (100%) rename {igor => src/igor}/__init__.py (100%) rename {igor => src/igor}/__init__.pyi (100%) rename {igor => src/igor}/_typing.py (100%) rename {igor => src/igor}/binarywave.py (100%) rename {igor => src/igor}/binarywave.pyi (100%) rename {igor => src/igor}/igorpy.py (100%) rename {igor => src/igor}/igorpy.pyi (100%) rename {igor => src/igor}/packed.py (100%) rename {igor => src/igor}/packed.pyi (100%) rename {igor => src/igor}/record/__init__.py (100%) rename {igor => src/igor}/record/__init__.pyi (100%) rename {igor => src/igor}/record/base.py (100%) rename {igor => src/igor}/record/base.pyi (100%) rename {igor => src/igor}/record/folder.py (100%) rename {igor => src/igor}/record/folder.pyi (100%) rename {igor => src/igor}/record/history.py (100%) rename {igor => src/igor}/record/history.pyi (100%) rename {igor => src/igor}/record/packedfile.py (100%) rename {igor => src/igor}/record/packedfile.pyi (100%) rename {igor => src/igor}/record/procedure.py (100%) rename {igor => src/igor}/record/procedure.pyi (100%) rename {igor => src/igor}/record/variables.py (100%) rename {igor => src/igor}/record/variables.pyi (100%) rename {igor => src/igor}/record/wave.py (100%) rename {igor => src/igor}/record/wave.pyi (100%) rename {igor => src/igor}/script.py (100%) rename {igor => src/igor}/script.pyi (100%) rename {igor => src/igor}/struct.py (100%) rename {igor => src/igor}/struct.pyi (100%) rename {igor => src/igor}/util.py (100%) rename {igor => src/igor}/util.pyi (100%) create mode 100644 test/data/ID_003.ibw diff --git a/.gitignore b/.gitignore index 89fdf58..e3fbbf7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,6 @@ __pycache__ *.py[cod] dist/ + +requirements-dev.lock +requirements.lock diff --git a/setup.py b/legacy_files/setup.py similarity index 100% rename from setup.py rename to legacy_files/setup.py diff --git a/pyproject.toml b/pyproject.toml index e05a2dc..e90576c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,11 +3,11 @@ name = "igorpy" version = "0.3.2" description = "Add your description here" authors = [ - { name = "W. Trevor King", email = "wking@tremily.us" }, - { name = "Conrad Stansbury", email = "chstan@berkely.edu" }, + { name = "W. Trevor King", email = "wking@tremily.us" }, + { name = "Conrad Stansbury", email = "chstan@berkely.edu" }, ] maintainers = [ - { name = "Ryuichi Arafune", email = "ryuichi.arafune@gmail.com" }, + { name = "Ryuichi Arafune", email = "ryuichi.arafune@gmail.com" }, ] dependencies = ["numpy"] readme = "README.md" @@ -26,4 +26,6 @@ allow-direct-references = true [tool.mypy] ignore_missing_imports = true -enable_incomplete_feature = ["Unpack"] + +[tool.hatch.build.targets.wheel] +packages = ["src/igorpy"] diff --git a/igor/__init__.py b/src/igor/__init__.py similarity index 100% rename from igor/__init__.py rename to src/igor/__init__.py diff --git a/igor/__init__.pyi b/src/igor/__init__.pyi similarity index 100% rename from igor/__init__.pyi rename to src/igor/__init__.pyi diff --git a/igor/_typing.py b/src/igor/_typing.py similarity index 100% rename from igor/_typing.py rename to src/igor/_typing.py diff --git a/igor/binarywave.py b/src/igor/binarywave.py similarity index 100% rename from igor/binarywave.py rename to src/igor/binarywave.py diff --git a/igor/binarywave.pyi b/src/igor/binarywave.pyi similarity index 100% rename from igor/binarywave.pyi rename to src/igor/binarywave.pyi diff --git a/igor/igorpy.py b/src/igor/igorpy.py similarity index 100% rename from igor/igorpy.py rename to src/igor/igorpy.py diff --git a/igor/igorpy.pyi b/src/igor/igorpy.pyi similarity index 100% rename from igor/igorpy.pyi rename to src/igor/igorpy.pyi diff --git a/igor/packed.py b/src/igor/packed.py similarity index 100% rename from igor/packed.py rename to src/igor/packed.py diff --git a/igor/packed.pyi b/src/igor/packed.pyi similarity index 100% rename from igor/packed.pyi rename to src/igor/packed.pyi diff --git a/igor/record/__init__.py b/src/igor/record/__init__.py similarity index 100% rename from igor/record/__init__.py rename to src/igor/record/__init__.py diff --git a/igor/record/__init__.pyi b/src/igor/record/__init__.pyi similarity index 100% rename from igor/record/__init__.pyi rename to src/igor/record/__init__.pyi diff --git a/igor/record/base.py b/src/igor/record/base.py similarity index 100% rename from igor/record/base.py rename to src/igor/record/base.py diff --git a/igor/record/base.pyi b/src/igor/record/base.pyi similarity index 100% rename from igor/record/base.pyi rename to src/igor/record/base.pyi diff --git a/igor/record/folder.py b/src/igor/record/folder.py similarity index 100% rename from igor/record/folder.py rename to src/igor/record/folder.py diff --git a/igor/record/folder.pyi b/src/igor/record/folder.pyi similarity index 100% rename from igor/record/folder.pyi rename to src/igor/record/folder.pyi diff --git a/igor/record/history.py b/src/igor/record/history.py similarity index 100% rename from igor/record/history.py rename to src/igor/record/history.py diff --git a/igor/record/history.pyi b/src/igor/record/history.pyi similarity index 100% rename from igor/record/history.pyi rename to src/igor/record/history.pyi diff --git a/igor/record/packedfile.py b/src/igor/record/packedfile.py similarity index 100% rename from igor/record/packedfile.py rename to src/igor/record/packedfile.py diff --git a/igor/record/packedfile.pyi b/src/igor/record/packedfile.pyi similarity index 100% rename from igor/record/packedfile.pyi rename to src/igor/record/packedfile.pyi diff --git a/igor/record/procedure.py b/src/igor/record/procedure.py similarity index 100% rename from igor/record/procedure.py rename to src/igor/record/procedure.py diff --git a/igor/record/procedure.pyi b/src/igor/record/procedure.pyi similarity index 100% rename from igor/record/procedure.pyi rename to src/igor/record/procedure.pyi diff --git a/igor/record/variables.py b/src/igor/record/variables.py similarity index 100% rename from igor/record/variables.py rename to src/igor/record/variables.py diff --git a/igor/record/variables.pyi b/src/igor/record/variables.pyi similarity index 100% rename from igor/record/variables.pyi rename to src/igor/record/variables.pyi diff --git a/igor/record/wave.py b/src/igor/record/wave.py similarity index 100% rename from igor/record/wave.py rename to src/igor/record/wave.py diff --git a/igor/record/wave.pyi b/src/igor/record/wave.pyi similarity index 100% rename from igor/record/wave.pyi rename to src/igor/record/wave.pyi diff --git a/igor/script.py b/src/igor/script.py similarity index 100% rename from igor/script.py rename to src/igor/script.py diff --git a/igor/script.pyi b/src/igor/script.pyi similarity index 100% rename from igor/script.pyi rename to src/igor/script.pyi diff --git a/igor/struct.py b/src/igor/struct.py similarity index 100% rename from igor/struct.py rename to src/igor/struct.py diff --git a/igor/struct.pyi b/src/igor/struct.pyi similarity index 100% rename from igor/struct.pyi rename to src/igor/struct.pyi diff --git a/igor/util.py b/src/igor/util.py similarity index 100% rename from igor/util.py rename to src/igor/util.py diff --git a/igor/util.pyi b/src/igor/util.pyi similarity index 100% rename from igor/util.pyi rename to src/igor/util.pyi diff --git a/test/data/ID_003.ibw b/test/data/ID_003.ibw new file mode 100644 index 0000000000000000000000000000000000000000..33a4af4c95f40d06cdc66f0c383205968385a407 GIT binary patch literal 437315 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 z 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 literal 0 HcmV?d00001 From b4dcd9eff33143cf6dfb701ce4d30a55205729f6 Mon Sep 17 00:00:00 2001 From: Ryuichi Arafune Date: Mon, 6 May 2024 10:03:25 +0900 Subject: [PATCH 15/16] Revise the code around logging --- src/igor/__init__.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/igor/__init__.py b/src/igor/__init__.py index e655275..9bdcbc0 100644 --- a/src/igor/__init__.py +++ b/src/igor/__init__.py @@ -19,16 +19,17 @@ "Interface for reading binary IGOR files." -__version__ = "0.3.2" +from logging import DEBUG, INFO, getLogger, Formatter, StreamHandler __all__ = ("__version__",) -import logging +__version__ = "0.3.2" -LOG = logging.getLogger("igor") -LOG.setLevel(logging.ERROR) -LOG.addHandler(logging.StreamHandler()) -LOG.handlers[-1].setFormatter( - logging.Formatter("%(name)s - %(levelname)s - %(message)s") -) +LOGLEVELS = (DEBUG, INFO) +LOGLEVEL = LOGLEVELS[1] +LOG = getLogger("igor") +LOG.setLevel(LOGLEVEL) +LOG.addHandler(StreamHandler()) +formatter = Formatter("%(name)s - %(levelname)s - %(message)s") +LOG.handlers[-1].setFormatter(formatter) From 0f992676f99cf6f452405c80de6bbe3300f11685 Mon Sep 17 00:00:00 2001 From: Ryuichi Arafune Date: Fri, 19 Jul 2024 14:24:39 +0900 Subject: [PATCH 16/16] =?UTF-8?q?=F0=9F=90=9B=20=20Fix=20but=20in=20pyproj?= =?UTF-8?q?ect.toml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e90576c..a87dd40 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,4 +28,4 @@ allow-direct-references = true ignore_missing_imports = true [tool.hatch.build.targets.wheel] -packages = ["src/igorpy"] +packages = ["src/igor"]