--- /dev/null
+# Copyright
+
+from .struct import Structure as _Structure
+from .struct import Field as _Field
+
+"Read IGOR Packed Experiment files files into records."
+
+
+class Record (object):
+ def __init__(self, header, data):
+ self.header = header
+ self.data = data
+
+ def __str__(self):
+ return self.__repr__()
+
+ def __repr__(self):
+ return '<{} {}>'.format(self.__class__.__name__, id(self))
+
+
+class UnknownRecord (Record):
+ def __repr__(self):
+ return '<{}-{} {}>'.format(
+ self.__class__.__name__, self.header['recordType'], id(self))
+
+
+class UnusedRecord (Record):
+ pass
+
+
+class VariablesRecord (Record):
+ pass
+
+
+class HistoryRecord (Record):
+ pass
+
+
+class WaveRecord (Record):
+ pass
+
+
+class RecreationRecord (Record):
+ pass
+
+
+class ProcedureRecord (Record):
+ pass
+
+
+class GetHistoryRecord (Record):
+ pass
+
+
+class PackedFileRecord (Record):
+ pass
+
+
+class FolderStartRecord (Record):
+ pass
+
+
+class FolderEndRecord (Record):
+ pass
+
+
+# From PackedFile.h
+RECORD_TYPE = {
+ 0: UnusedRecord,
+ 1: VariablesRecord,
+ 2: HistoryRecord,
+ 3: WaveRecord,
+ 4: RecreationRecord,
+ 5: ProcedureRecord,
+ 6: UnusedRecord,
+ 7: GetHistoryRecord,
+ 8: PackedFileRecord,
+ 9: FolderStartRecord,
+ 10: FolderEndRecord,
+ }
+
+# Igor writes other kinds of records in a packed experiment file, for
+# storing things like pictures, page setup records, and miscellaneous
+# settings. The format for these records is quite complex and is not
+# described in PTN003. If you are writing a program to read packed
+# files, you must skip any record with a record type that is not
+# listed above.
+
+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)
+
+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.
+
+
+def load(filename, strict=True, ignore_unknown=True):
+ records = []
+ if hasattr(filename, 'read'):
+ f = filename # filename is actually a stream object
+ else:
+ f = open(filename, 'rb')
+ try:
+ while True:
+ PackedFileRecordHeader.set_byte_order('=')
+ b = buffer(f.read(PackedFileRecordHeader.size))
+ if not b:
+ break
+ header = PackedFileRecordHeader.unpack_dict_from(b)
+ data = f.read(header['numDataBytes'])
+ record_type = RECORD_TYPE.get(
+ header['recordType'] & PACKEDRECTYPE_MASK, UnknownRecord)
+ if record_type in [UnknownRecord, UnusedRecord
+ ] and not ignore_unknown:
+ raise KeyError('unkown record type {}'.format(
+ header['recordType']))
+ records.append(record_type(header, data))
+ finally:
+ if not hasattr(filename, 'read'):
+ f.close()
+
+ return records
+
r"""Test the igor module by loading sample files.
->>> dump('mac-double.ibw', strict=False) # doctest: +REPORT_UDIFF
+>>> dumpibw('mac-double.ibw', strict=False) # doctest: +REPORT_UDIFF
array([ 5., 4., 3., 2., 1.])
{'checksum': 25137,
'note': '',
'xUnits': array(['', '', '', ''],
dtype='|S1')}
->>> dump('mac-textWave.ibw') # doctest: +REPORT_UDIFF
+>>> dumpibw('mac-textWave.ibw') # doctest: +REPORT_UDIFF
array(['Mary', 'had', 'a', 'little', 'lamb'],
dtype='|S6')
{'checksum': 5554,
'whpad3': 0,
'whpad4': 0}
->>> dump('mac-version2.ibw', strict=False) # doctest: +REPORT_UDIFF
+>>> dumpibw('mac-version2.ibw', strict=False) # doctest: +REPORT_UDIFF
array([ 5., 4., 3., 2., 1.], dtype=float32)
{'checksum': -16803,
'note': 'This is a test.',
'xUnits': array(['', '', '', ''],
dtype='|S1')}
->>> dump('mac-version3Dependent.ibw', strict=False) # doctest: +REPORT_UDIFF
+>>> dumpibw('mac-version3Dependent.ibw', strict=False) # doctest: +REPORT_UDIFF
array([], dtype=int8)
{'checksum': 0,
'formula': '',
'xUnits': array(['', '', '', ''],
dtype='|S1')}
->>> dump('mac-version5.ibw') # doctest: +REPORT_UDIFF
+>>> dumpibw('mac-version5.ibw') # doctest: +REPORT_UDIFF
array([ 5., 4., 3., 2., 1.], dtype=float32)
{'checksum': -12033,
'dataEUnits': '',
'whpad3': 0,
'whpad4': 0}
->>> dump('mac-zeroPointWave.ibw') # doctest: +REPORT_UDIFF
+>>> dumpibw('mac-zeroPointWave.ibw') # doctest: +REPORT_UDIFF
array([], dtype=float32)
{'checksum': -15649,
'dataEUnits': '',
'whpad3': 0,
'whpad4': 0}
->>> dump('win-double.ibw') # doctest: +REPORT_UDIFF
+>>> dumpibw('win-double.ibw') # doctest: +REPORT_UDIFF
array([ 5., 4., 3., 2., 1.])
{'checksum': 28962,
'note': '',
'xUnits': array(['', '', '', ''],
dtype='|S1')}
->>> dump('win-textWave.ibw') # doctest: +REPORT_UDIFF
+>>> dumpibw('win-textWave.ibw') # doctest: +REPORT_UDIFF
array(['Mary', 'had', 'a', 'little', 'lamb'],
dtype='|S6')
{'checksum': 184,
'whpad3': 0,
'whpad4': 0}
->>> dump('win-version2.ibw') # doctest: +REPORT_UDIFF
+>>> dumpibw('win-version2.ibw') # doctest: +REPORT_UDIFF
array([ 5., 4., 3., 2., 1.], dtype=float32)
{'checksum': 1047,
'note': 'This is a test.',
'xUnits': array(['', '', '', ''],
dtype='|S1')}
->>> dump('win-version5.ibw') # doctest: +REPORT_UDIFF
+>>> dumpibw('win-version5.ibw') # doctest: +REPORT_UDIFF
array([ 5., 4., 3., 2., 1.], dtype=float32)
{'checksum': 13214,
'dataEUnits': '',
'whpad3': 0,
'whpad4': 0}
->>> dump('win-zeroPointWave.ibw') # doctest: +REPORT_UDIFF
+>>> dumpibw('win-zeroPointWave.ibw') # doctest: +REPORT_UDIFF
array([], dtype=float32)
{'checksum': 27541,
'dataEUnits': '',
'whpad2': 0,
'whpad3': 0,
'whpad4': 0}
+
+>>> dumppxp('polar-graphs-demo.pxp') # doctest: +REPORT_UDIFF, +ELLIPSIS
+record 0:
+<UnknownRecord-11 ...>
+record 1:
+<UnknownRecord-12 ...>
+record 2:
+<UnknownRecord-13 ...>
+record 3:
+<UnknownRecord-13 ...>
+record 4:
+<UnknownRecord-13 ...>
+record 5:
+<UnknownRecord-13 ...>
+record 6:
+<UnknownRecord-13 ...>
+record 7:
+<UnknownRecord-13 ...>
+record 8:
+<UnknownRecord-13 ...>
+record 9:
+<UnknownRecord-14 ...>
+record 10:
+<UnknownRecord-15 ...>
+record 11:
+<UnknownRecord-16 ...>
+record 12:
+<UnknownRecord-16 ...>
+record 13:
+<UnknownRecord-17 ...>
+record 14:
+<UnknownRecord-17 ...>
+record 15:
+<UnknownRecord-17 ...>
+record 16:
+<UnknownRecord-17 ...>
+record 17:
+<UnknownRecord-17 ...>
+record 18:
+<UnknownRecord-17 ...>
+record 19:
+<UnknownRecord-16 ...>
+record 20:
+<UnknownRecord-17 ...>
+record 21:
+<UnknownRecord-17 ...>
+record 22:
+<UnknownRecord-17 ...>
+record 23:
+<UnknownRecord-17 ...>
+record 24:
+<UnknownRecord-17 ...>
+record 25:
+<UnknownRecord-17 ...>
+record 26:
+<UnknownRecord-18 ...>
+record 27:
+<UnknownRecord-11 ...>
+record 28:
+<UnknownRecord-26 ...>
+record 29:
+<UnknownRecord-26 ...>
+record 30:
+<VariablesRecord ...>
+record 31:
+<HistoryRecord ...>
+record 32:
+<WaveRecord ...>
+record 33:
+<WaveRecord ...>
+record 34:
+<WaveRecord ...>
+record 35:
+<WaveRecord ...>
+record 36:
+<WaveRecord ...>
+record 37:
+<WaveRecord ...>
+record 38:
+<WaveRecord ...>
+record 39:
+<WaveRecord ...>
+record 40:
+<FolderStartRecord ...>
+record 41:
+<FolderStartRecord ...>
+record 42:
+<VariablesRecord ...>
+record 43:
+<FolderEndRecord ...>
+record 44:
+<FolderStartRecord ...>
+record 45:
+<VariablesRecord ...>
+record 46:
+<FolderEndRecord ...>
+record 47:
+<FolderEndRecord ...>
+record 48:
+<RecreationRecord ...>
+record 49:
+<GetHistoryRecord ...>
+record 50:
+<ProcedureRecord ...>
"""
import os.path
import sys
from igor.binarywave import loadibw
+from igor.packed import load as loadpxp
_this_dir = os.path.dirname(__file__)
_data_dir = os.path.join(_this_dir, 'data')
-def dump(filename, strict=True):
+def dumpibw(filename, strict=True):
sys.stderr.write('Testing {}\n'.format(filename))
path = os.path.join(_data_dir, filename)
data,bin_info,wave_info = loadibw(path, strict=strict)
pprint(bin_info)
pprint(wave_info)
+def dumppxp(filename, strict=True):
+ sys.stderr.write('Testing {}\n'.format(filename))
+ path = os.path.join(_data_dir, filename)
+ records = loadpxp(path, strict=strict)
+ for i,record in enumerate(records):
+ print('record {}:'.format(i))
+ pprint(record)
+
def pprint(data):
lines = pformat(data).splitlines()
print('\n'.join([line.rstrip() for line in lines]))