From e580ecae8c66134b1e9ba73cfaa358948a96fb1c Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Sun, 16 Sep 2018 23:20:04 +0200 Subject: [PATCH 01/61] in case nBits ==0, nBytes shall be also 0 --- mdfreader/mdf.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mdfreader/mdf.py b/mdfreader/mdf.py index 350343f..6fc9959 100644 --- a/mdfreader/mdf.py +++ b/mdfreader/mdf.py @@ -703,7 +703,9 @@ def _bits_to_bytes(nBits, numeric=True): number of equivalent bytes """ if numeric: - if nBits <= 8: + if nBits == 0: + nBytes = 0 + elif nBits <= 8: nBytes = 1 elif nBits <= 16: nBytes = 2 From 6381639b3395d58321c45f9f25d3908775de38ac Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Mon, 17 Sep 2018 20:50:15 +0200 Subject: [PATCH 02/61] changed calculations bsed on number of byes and not number of bits for reading data. --- mdfreader/channel.py | 249 ++++++++++++++++++++++------------------ mdfreader/mdf3reader.py | 26 +++-- mdfreader/mdf4reader.py | 8 +- 3 files changed, 157 insertions(+), 126 deletions(-) diff --git a/mdfreader/channel.py b/mdfreader/channel.py index bdcaf84..f66d2f6 100644 --- a/mdfreader/channel.py +++ b/mdfreader/channel.py @@ -125,6 +125,8 @@ class channel4(object): dict of invalid bit channels data invalid_bytes : bytes byte containing invalid bit for each channel + bit_masking_needed : boolean + False if channel needs bit masking """ def __init__(self): @@ -264,8 +266,7 @@ def bitCount(self, info): integer corresponding to channel number of bits """ if self.type in ('std', 'CA', 'NestCA'): - return info['CN'][self.dataGroup][self.channelGroup]\ - [self.channelNumber]['cn_bit_count'] + return info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_bit_count'] elif self.type == 'CAN': if self.name == 'ms': if self.signalDataType(info) == 13: @@ -303,7 +304,7 @@ def channelSyncType(self, info): return info['CN'][self.dataGroup][self.channelGroup]\ [self.channelNumber]['cn_sync_type'] except KeyError: - return 0 # in case of invaldi bytes channel + return 0 # in case of invalid bytes channel def CABlock(self, info): """ Extracts channel CA Block from info4 @@ -373,7 +374,7 @@ def channelType(self, info): try: return info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_type'] except KeyError: - return 0 # in case of invaldi bytes channel + return 0 # in case of invalid bytes channel def isnumeric(self, info): """ check this is numeric channel from data type @@ -406,9 +407,10 @@ def nBytes(self, info): ----------- number of bytes integer """ - if not self.type == 'Inv': - nBytes = _bits_to_bytes(info['CN'][self.dataGroup][self.channelGroup]\ - [self.channelNumber]['cn_bit_count'], self.isnumeric(info)) + if not self.type == 'Inv': # not channel containing invalid bits + nBytes = _bits_to_bytes(info['CN'][self.dataGroup][self.channelGroup] + [self.channelNumber]['cn_bit_count'] + info['CN'][self.dataGroup][self.channelGroup] + [self.channelNumber]['cn_bit_offset'], self.isnumeric(info)) if self.type in ('CA', 'NestCA'): nBytes *= self.CABlock(info)['PNd'] Block = self.CABlock(info) @@ -484,13 +486,12 @@ def numpy_format(self, info): CABlock = info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['CABlock'] endian, dataformat = arrayformat4( info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_data_type'], - info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_bit_count']) + info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_bit_count'] // 8) # calculates total array size in bytes array_desc = CABlock['ca_dim_size'] Block = CABlock while 'CABlock' in Block: # nested array Block = Block['CABlock'] - Block['ca_dim_size'] if isinstance(array_desc, list): array_desc.append(Block['ca_dim_size']) else: @@ -514,7 +515,7 @@ def numpy_format(self, info): else: # not channel array endian, dataformat = arrayformat4( info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_data_type'], - info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_bit_count']) + self.nBytes(info)) return endian, dataformat def dataFormat(self, info): @@ -554,9 +555,9 @@ def Format(self, info): signalDataType = self.signalDataType(info) if signalDataType not in (13, 14): if not self.channelType(info) == 1: # if not VSLD - return datatypeformat4(signalDataType, self.bitCount(info)) + return datatypeformat4(signalDataType, self.nBytes(info)) else: # VLSD - return datatypeformat4(0, self.bitCount(info)) + return datatypeformat4(0, self.nBytes(info)) elif self.type == 'CAN': if self.name == 'ms': if self.signalDataType == 13: @@ -631,11 +632,10 @@ def bitOffset(self, info): integer, channel bit offset """ if self.type in ('std', 'CA', 'NestCA'): - return info['CN'][self.dataGroup][self.channelGroup]\ - [self.channelNumber]['cn_bit_offset'] + return info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_bit_offset'] elif self.type == 'CAN': - return info['CN'][self.dataGroup][self.channelGroup]\ - [self.channelNumber]['cn_bit_offset'] + self.CANOpenOffset(info)*8 + return info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_bit_offset'] \ + + self.CANOpenOffset(info) * 8 elif self.type == 'Inv': return 0 else: @@ -911,16 +911,35 @@ def changeChannelName(self, channelGroup): """ self.name = '{0}_{1}'.format(self.name, channelGroup) + def bit_masking_needed(self, info): + """ Valid if bit masking need + + Parameters + ---------------- + + info : mdfinfo4.info4 class + info4 class containing all MDF Blocks + + Returns + ----------- + boolean True if channel needs bit masking, otherwise False + + """ + if not self.nBytes(info) == self.bitCount(info) / 8: + self.bit_masking_needed = True + else: + self.bit_masking_needed = False + -def arrayformat4(signalDataType, numberOfBits): +def arrayformat4(signalDataType, numberOfBytes): """ function returning numpy style string from channel data type and number of bits Parameters ---------------- signalDataType : int channel data type according to specification - numberOfBits : int - number of bits taken by channel data in a record + numberOfBytes : int + number of bytes taken by channel data in a record Returns ----------- @@ -929,111 +948,111 @@ def arrayformat4(signalDataType, numberOfBits): """ if signalDataType == 0: # unsigned, low endian - if numberOfBits <= 8: + if numberOfBytes == 1: dataType = 'u1' - elif numberOfBits <= 16: + elif numberOfBytes == 2: dataType = 'u2' - elif numberOfBits <= 32: + elif numberOfBytes <= 4: dataType = 'u4' - elif numberOfBits <= 64: + elif numberOfBytes <= 8: dataType = 'u8' else: - dataType = '{}V'.format(_bits_to_bytes(numberOfBits) // 8) + dataType = '{}V'.format(numberOfBytes) endian = '<' elif signalDataType == 2: # signed int, low endian - if numberOfBits <= 8: + if numberOfBytes == 1: dataType = 'i1' - elif numberOfBits <= 16: + elif numberOfBytes == 2: dataType = 'i2' - elif numberOfBits <= 32: + elif numberOfBytes <= 4: dataType = 'i4' - elif numberOfBits <= 64: + elif numberOfBytes <= 8: dataType = 'i8' else: - warn('Unsupported number of bits for signed int {}'.format(numberOfBits)) + warn('Unsupported number of bytes for signed int {}'.format(numberOfBytes)) endian = '<' elif signalDataType == 4: # floating point, low endian - if numberOfBits == 32: + if numberOfBytes == 4: dataType = 'f4' - elif numberOfBits == 64: + elif numberOfBytes == 8: dataType = 'f8' else: - warn('Unsupported number of bit for floating point {}'.format(numberOfBits)) + warn('Unsupported number of bytes for floating point {}'.format(numberOfBytes)) endian = '<' elif signalDataType == 1: # unsigned, big endian - if numberOfBits <= 8: + if numberOfBytes == 1: dataType = 'u1' - elif numberOfBits <= 16: + elif numberOfBytes == 2: dataType = 'u2' - elif numberOfBits <= 32: + elif numberOfBytes <= 4: dataType = 'u4' - elif numberOfBits <= 64: + elif numberOfBytes <= 8: dataType = 'u8' else: - dataType = '{}V'.format(_bits_to_bytes(numberOfBits) // 8) + dataType = '{}V'.format(numberOfBytes) endian = '>' elif signalDataType == 3: # signed int, big endian - if numberOfBits <= 8: + if numberOfBytes == 1: dataType = 'i1' - elif numberOfBits <= 16: + elif numberOfBytes == 2: dataType = 'i2' - elif numberOfBits <= 32: + elif numberOfBytes <= 4: dataType = 'i4' - elif numberOfBits <= 64: + elif numberOfBytes <= 8: dataType = 'i8' else: - warn('Unsupported number of bits for signed int {}'.format(numberOfBits)) + warn('Unsupported number of bytes for signed int {}'.format(numberOfBytes)) endian = '>' elif signalDataType == 5: # floating point, big endian - if numberOfBits == 32: + if numberOfBytes == 4: dataType = 'f4' - elif numberOfBits == 64: + elif numberOfBytes == 8: dataType = 'f8' else: - warn('Unsupported number of bit for floating point {}'.format(numberOfBits)) + warn('Unsupported number of bytes for floating point {}'.format(numberOfBytes)) endian = '>' elif signalDataType == 6: # string ISO-8859-1 Latin - dataType = 'S{}'.format(numberOfBits // 8) + dataType = 'S{}'.format(numberOfBytes) endian = '' elif signalDataType == 7: # UTF-8 - dataType = 'S{}'.format(numberOfBits // 8) + dataType = 'S{}'.format(numberOfBytes) endian = '' elif signalDataType == 8: # UTF-16 low endian - dataType = 'S{}'.format(numberOfBits // 8) + dataType = 'S{}'.format(numberOfBytes) endian = '<' elif signalDataType == 9: # UTF-16 big endian - dataType = 'S{}'.format(numberOfBits // 8) + dataType = 'S{}'.format(numberOfBytes) endian = '>' elif signalDataType == 10: # bytes array - dataType = 'V{}'.format(numberOfBits // 8) + dataType = 'V{}'.format(numberOfBytes) endian = '' elif signalDataType in (11, 12): # MIME sample or MIME stream - dataType = 'V{}'.format(int(numberOfBits / 8)) + dataType = 'V{}'.format(numberOfBytes) endian = '' elif signalDataType in (13, 14): # CANOpen date or time dataType = '' endian = '' else: - warn('Unsupported Signal Data Type {} {}'.format(signalDataType, numberOfBits)) + warn('Unsupported Signal Data Type {} {}'.format(signalDataType, numberOfBytes)) return endian, dataType -def datatypeformat4(signalDataType, numberOfBits): +def datatypeformat4(signalDataType, numberOfBytes): """ function returning C format string from channel data type and number of bits Parameters ---------------- signalDataType : int channel data type according to specification - numberOfBits : int - number of bits taken by channel data in a record + numberOfBytes : int + number of bytes taken by channel data in a record Returns ----------- @@ -1042,41 +1061,41 @@ def datatypeformat4(signalDataType, numberOfBits): """ if signalDataType in (0, 1): # unsigned int - if numberOfBits <= 8: + if numberOfBytes == 1: dataType = 'B' - elif numberOfBits <= 16: + elif numberOfBytes == 2: dataType = 'H' - elif numberOfBits <= 32: + elif numberOfBytes <= 4: dataType = 'I' - elif numberOfBits <= 64: + elif numberOfBytes <= 8: dataType = 'Q' else: - dataType = '{}s'.format(_bits_to_bytes(numberOfBits) // 8) + dataType = '{}s'.format(numberOfBytes) elif signalDataType in (2, 3): # signed int - if numberOfBits <= 8: + if numberOfBytes == 1: dataType = 'b' - elif numberOfBits <= 16: + elif numberOfBytes == 2: dataType = 'h' - elif numberOfBits <= 32: + elif numberOfBytes <= 4: dataType = 'i' - elif numberOfBits <= 64: + elif numberOfBytes <= 8: dataType = 'q' else: - warn('Unsupported number of bits for signed int {}'.format(signalDataType)) + warn('Unsupported number of bytes for signed int {}'.format(signalDataType)) elif signalDataType in (4, 5): # floating point - if numberOfBits == 32: + if numberOfBytes == 4: dataType = 'f' - elif numberOfBits == 64: + elif numberOfBytes == 8: dataType = 'd' else: - warn('Unsupported number of bit for floating point {}'.format(signalDataType)) + warn('Unsupported number of bytes for floating point {}'.format(signalDataType)) elif signalDataType in (6, 7, 8, 9, 10, 11, 12): # string/bytes - dataType = '{}s'.format(numberOfBits // 8) + dataType = '{}s'.format(numberOfBytes) else: - warn('Unsupported Signal Data Type {} {}'.format(signalDataType, numberOfBits)) + warn('Unsupported Signal Data Type {} {}'.format(signalDataType, numberOfBytes)) # deal with byte order if signalDataType in (0, 2, 4, 8): # low endian dataType = '<{}'.format(dataType) @@ -1129,6 +1148,8 @@ class Channel3: start position in number of bit of channel record in complete record posByteEnd : int end position in number of bit of channel record in complete record + bit_masking_needed : bool, default false + True if bit masking needed after data read Methods ------------ @@ -1157,23 +1178,27 @@ def __init__(self, info, dataGroup, channelGroup, self.name = info['CNBlock'][dataGroup][channelGroup][channelNumber]['signalName'] self.channelNumber = channelNumber self.signalDataType = info['CNBlock'][dataGroup][channelGroup][channelNumber]['signalDataType'] - self.bitCount = info['CNBlock'][dataGroup][channelGroup][channelNumber]['numberOfBits'] - ByteOrder = info['IDBlock']['ByteOrder'] - (self.dataFormat, self.nativedataFormat) = \ - _arrayformat3(self.signalDataType, self.bitCount, ByteOrder) - self.CFormat = Struct(_datatypeformat3(self.signalDataType, self.bitCount, ByteOrder)) if not self.signalDataType in (7, 8): numeric = True else: numeric = False - self.nBytes = _bits_to_bytes(self.bitCount, numeric) + self.bitCount = info['CNBlock'][dataGroup][channelGroup][channelNumber]['numberOfBits'] + ByteOrder = info['IDBlock']['ByteOrder'] self.posBitBeg = info['CNBlock'][dataGroup][channelGroup][channelNumber]['numberOfTheFirstBits'] self.posBitEnd = self.posBitBeg + self.bitCount - self.byteOffset = self.posBitBeg // 8 # + info['CNBlock'][dataGroup][channelGroup][channelNumber]['ByteOffset'] + self.byteOffset = self.posBitBeg // 8 self.bitOffset = self.posBitBeg % 8 + self.nBytes = _bits_to_bytes(self.bitCount + self.bitOffset, numeric) + (self.dataFormat, self.nativedataFormat) = \ + _arrayformat3(self.signalDataType, self.nBytes, ByteOrder) + self.CFormat = Struct(_datatypeformat3(self.signalDataType, self.nBytes, ByteOrder)) self.embedding_channel_bitOffset = self.bitOffset # for channel containing other channels self.posByteBeg = recordIDnumber + self.byteOffset self.posByteEnd = recordIDnumber + self.byteOffset + self.nBytes + if not self.nBytes == self.bitCount / 8: + self.bit_masking_needed = True + else: + self.bit_masking_needed = False self.channelType = info['CNBlock'][dataGroup][channelGroup][channelNumber]['channelType'] if 'physicalUnit' in info['CCBlock'][dataGroup][channelGroup][channelNumber]: self.unit = info['CCBlock'][dataGroup][channelGroup][channelNumber]['physicalUnit'] @@ -1205,15 +1230,15 @@ def changeChannelName(self, channelGroup): self.RecordFormat = (('{}_title'.format(self.recAttributeName), self.recAttributeName), self.dataFormat) -def _datatypeformat3(signalDataType, numberOfBits, ByteOrder): +def _datatypeformat3(signalDataType, numberOfBytes, ByteOrder): """ function returning C format string from channel data type and number of bits Parameters ---------------- signalDataType : int channel data type according to specification - numberOfBits : int - number of bits taken by channel data in a record + numberOfBytes : int + number of bytes taken by channel data in a record Returns ----------- @@ -1221,43 +1246,43 @@ def _datatypeformat3(signalDataType, numberOfBits, ByteOrder): C format used by fread to read channel raw data """ if signalDataType in (0, 9, 13): # unsigned - if numberOfBits <= 8: + if numberOfBytes == 1: dataType = 'B' - elif numberOfBits <= 16: + elif numberOfBytes == 2: dataType = 'H' - elif numberOfBits <= 32: + elif numberOfBytes <= 4: dataType = 'I' - elif numberOfBits <= 64: + elif numberOfBytes <= 8: dataType = 'Q' else: warn('Unsupported number of bits for unsigned int {}'.format(signalDataType)) elif signalDataType in (1, 10, 14): # signed int - if numberOfBits <= 8: + if numberOfBytes == 1: dataType = 'b' - elif numberOfBits <= 16: + elif numberOfBytes == 2: dataType = 'h' - elif numberOfBits <= 32: + elif numberOfBytes <= 4: dataType = 'i' - elif numberOfBits <= 64: + elif numberOfBytes <= 8: dataType = 'q' else: warn('Unsupported number of bits for signed int {}'.format(signalDataType)) elif signalDataType in (2, 3, 11, 12, 15, 16): # floating point - if numberOfBits == 32: + if numberOfBytes == 4: dataType = 'f' - elif numberOfBits == 64: + elif numberOfBytes == 8: dataType = 'd' else: warn('Unsupported number of bit for floating point {}'.format(signalDataType)) elif signalDataType == 7: # string - dataType = str(numberOfBits // 8) + 's' + dataType = str(numberOfBytes) + 's' elif signalDataType == 8: # array of bytes - dataType = str(numberOfBits // 8) + 's' + dataType = str(numberOfBytes) + 's' else: - warn('Unsupported Signal Data Type {0} nBits {1}'.format(signalDataType, numberOfBits)) + warn('Unsupported Signal Data Type {0} nBits {1}'.format(signalDataType, numberOfBytes)) # deal with byte order if signalDataType in (0, 1, 2, 3): @@ -1273,14 +1298,14 @@ def _datatypeformat3(signalDataType, numberOfBits, ByteOrder): return dataType -def _arrayformat3(signalDataType, numberOfBits, ByteOrder): +def _arrayformat3(signalDataType, numberOfBytes, ByteOrder): """ function returning numpy style string from channel data type and number of bits Parameters ---------------- signalDataType : int channel data type according to specification - numberOfBits : int - number of bits taken by channel data in a record + numberOfBytes : int + number of bytes taken by channel data in a record Returns ----------- @@ -1290,43 +1315,43 @@ def _arrayformat3(signalDataType, numberOfBits, ByteOrder): # Formats used by numpy if signalDataType in (0, 9, 13): # unsigned - if numberOfBits <= 8: + if numberOfBytes == 1: dataType = 'u1' - elif numberOfBits <= 16: + elif numberOfBytes == 2: dataType = 'u2' - elif numberOfBits <= 32: + elif numberOfBytes <= 4: dataType = 'u4' - elif numberOfBits <= 64: + elif numberOfBytes <= 8: dataType = 'u8' else: - warn('Unsupported number of bits for unsigned int {} nBits '.format(signalDataType, numberOfBits)) + warn('Unsupported number of bits for unsigned int {} nBits '.format(signalDataType, numberOfBytes)) elif signalDataType in (1, 10, 14): # signed int - if numberOfBits <= 8: + if numberOfBytes == 1: dataType = 'i1' - elif numberOfBits <= 16: + elif numberOfBytes == 2: dataType = 'i2' - elif numberOfBits <= 32: + elif numberOfBytes <= 4: dataType = 'i4' - elif numberOfBits <= 64: + elif numberOfBytes <= 8: dataType = 'i8' else: - warn('Unsupported number of bits for signed int {0} nBits {1}'.format(signalDataType, numberOfBits)) + warn('Unsupported number of bits for signed int {0} nBits {1}'.format(signalDataType, numberOfBytes)) elif signalDataType in (2, 3, 11, 12, 15, 16): # floating point - if numberOfBits == 32: + if numberOfBytes == 4: dataType = 'f4' - elif numberOfBits == 64: + elif numberOfBytes == 8: dataType = 'f8' else: - warn('Unsupported number of bit for floating point {0} nBits {1}'.format(signalDataType, numberOfBits)) + warn('Unsupported number of bit for floating point {0} nBits {1}'.format(signalDataType, numberOfBytes)) elif signalDataType == 7: # string - dataType = 'S{}'.format(numberOfBits // 8) # not directly processed + dataType = 'S{}'.format(numberOfBytes) # not directly processed elif signalDataType == 8: # array of bytes - dataType = 'V{}'.format(numberOfBits // 8) # not directly processed + dataType = 'V{}'.format(numberOfBytes) # not directly processed else: - warn('Unsupported Signal Data Type {0} nBits {1}'.format(signalDataType, numberOfBits)) + warn('Unsupported Signal Data Type {0} nBits {1}'.format(signalDataType, numberOfBytes)) nativeDataType = dataType # deal with byte order diff --git a/mdfreader/mdf3reader.py b/mdfreader/mdf3reader.py index 938b46d..910b542 100644 --- a/mdfreader/mdf3reader.py +++ b/mdfreader/mdf3reader.py @@ -53,6 +53,7 @@ chunk_size_reading = 100000000 # reads by chunk of 100Mb, can be tuned for best performance + def linearConv(data, conv): # 0 Parametric, Linear: Physical =Integer*P2 + P1 """ apply linear conversion to data @@ -454,7 +455,7 @@ def loadInfo(self, info): # check for hidden bytes if self.CGrecordLength > self.recordLength: self.hiddenBytes = True - # check record length consitency + # check record length consistency elif self.CGrecordLength < self.recordLength: # forces to use dataRead instead of numpy records. self.byte_aligned = False @@ -535,7 +536,7 @@ def readSortedRecord(self, fid, pointer, channelSet=None): 13: 0, 14: 2, 15: 4, 16: 4} for nrecord_chunk, chunk_size in chunks: bita = fid.read(chunk_size) - for chan in recChan: + for id, chan in enumerate(recChan): rec[chan.name][previous_index: previous_index + nrecord_chunk] = \ dataRead(bytes(bita), chan.bitCount, @@ -546,6 +547,7 @@ def readSortedRecord(self, fid, pointer, channelSet=None): chan.bitOffset, chan.posByteBeg, chan.posByteEnd, 0) + self[id].bit_masking_needed = False # masking already considered in dataRead previous_index += nrecord_chunk return rec except: @@ -760,13 +762,19 @@ def loadUnSorted(self, nameList=None): for recordID in self: for channelName in self[recordID]['record'].dataRecordName: buf[channelName] = [] + if self[recordID]['record'].hiddenBytes or not self[recordID]['record'].byte_aligned: + for ind, chan in enumerate(self[recordID]['record']): + # will already extract bits, no need of masking later + self[recordID]['record'][ind].bit_masking_needed = False # read data while position < len(stream): recordID = recordIdCFormat.unpack(stream[position:position + 1])[0] if not self[recordID]['record'].hiddenBytes and self[recordID]['record'].byte_aligned: - temp = self[recordID]['record'].readRecordBuf(stream[position:position + self[recordID]['record'].CGrecordLength + 1], nameList) - else: # do read bytes but bits in record - temp = self[recordID]['record'].readRecordBits(stream[position:position + self[recordID]['record'].CGrecordLength + 1], nameList) + temp = self[recordID]['record'].readRecordBuf( + stream[position:position + self[recordID]['record'].CGrecordLength + 1], nameList) + else: # do not read bytes but bits in record + temp = self[recordID]['record'].readRecordBits( + stream[position:position + self[recordID]['record'].CGrecordLength + 1], nameList) # recordId is only unit8 position += self[recordID]['record'].CGrecordLength + 1 for channelName in temp: @@ -948,18 +956,14 @@ def read3(self, fileName=None, info=None, multiProc=False, channelList=None, if len(temp) != 0: # Process concatenated bits inside uint8 - if not chan.bitCount // 8.0 == chan.bitCount / 8.0 \ - and not buf[recordID]['record'].hiddenBytes \ - and buf[recordID]['record'].byte_aligned \ - and channelSet is None: + if chan.bit_masking_needed: # if channel data do not use complete bytes if chan.signalDataType in (0, 1, 9, 10, 13, 14): # integers temp = right_shift(temp, chan.embedding_channel_bitOffset) mask = int(pow(2, chan.bitCount) - 1) # masks isBitUint8 temp = bitwise_and(temp, mask) else: # should not happen - warn('bit count and offset not applied ' - 'to correct data type') + warn('bit count and offset not applied to correct data type') self.add_channel(dataGroup, chan.name, temp, master_channel, master_type=1, diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index 288dfc8..07d5d1c 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -439,7 +439,7 @@ def load(self, record, info, nameList=None, sortedFlag=True, vlsd=False): temp.read(self.fid) temps.update(temp) self.pointerTodata = temps['hl_dl_first'] - temps['data'] = self.load(record, info, nameList=nameList, sortedFlag=sortedFlag) + temps['data'] = self.load(record, info, nameList=nameList, sortedFlag=sortedFlag, vlsd=vlsd) elif temps['id'] in ('##DT', '##RD', b'##DT', b'##RD'): # normal sorted data block, direct read temps['data'] = record.readSortedRecord(self.fid, info, channelSet=nameList) elif temps['id'] in ('##SD', b'##SD'): # VLSD @@ -919,7 +919,8 @@ def initialise_recarray(self, info, channelSet, nrecords, dtype=None, channels_i names = [] channels_indexes = [] for chan in range(len(self)): - if self[chan].name in channelSet: + if self[chan].name in channelSet and self[chan].channelType(info) not in (3, 6): + # not virtual channel and part of channelSet channels_indexes.append(chan) formats.append(self[chan].nativedataFormat(info)) names.append(self[chan].name) @@ -1278,7 +1279,8 @@ def returnField(obj, field): signBitMask = (1 << (bitCount - 1)) signExtend = ((1 << (temp.itemsize * 8 - bitCount)) - 1) << bitCount signBit = bitwise_and(temp, signBitMask) - for number, sign in enumerate(signBit): # negative value, sign extend + for number, sign in enumerate(signBit): + # negative value, sign extend if sign: temp[number] |= signExtend else: # should not happen From 7b47b12ff4055a4494e7681c4038cba93a401c7c Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Mon, 17 Sep 2018 22:10:05 +0200 Subject: [PATCH 03/61] adapted Format and CFormat for arrays --- mdfreader/channel.py | 83 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 16 deletions(-) diff --git a/mdfreader/channel.py b/mdfreader/channel.py index f66d2f6..5bd7e5f 100644 --- a/mdfreader/channel.py +++ b/mdfreader/channel.py @@ -551,16 +551,24 @@ def Format(self, info): ----------- string data C format """ - if self.type in ('std', 'CA', 'NestCA'): - signalDataType = self.signalDataType(info) + signalDataType = self.signalDataType(info) + if self.type == 'std': if signalDataType not in (13, 14): if not self.channelType(info) == 1: # if not VSLD - return datatypeformat4(signalDataType, self.nBytes(info)) + endian, dataType = datatypeformat4(signalDataType, self.nBytes(info)) else: # VLSD - return datatypeformat4(0, self.nBytes(info)) + endian, dataType = datatypeformat4(0, self.nBytes(info)) + return '{}{}'.format(endian, dataType) + elif self.type in ('CA', 'NestCA'): + CA = self.CABlock(info) + nBytes = _bits_to_bytes(info['CN'][self.dataGroup][self.channelGroup] + [self.channelNumber]['cn_bit_count'] + info['CN'][self.dataGroup][self.channelGroup] + [self.channelNumber]['cn_bit_offset'], self.isnumeric(info)) + endian, dataType = datatypeformat4(signalDataType, nBytes) + return '{}{}{}'.format(endian, CA['PNd'], dataType) elif self.type == 'CAN': if self.name == 'ms': - if self.signalDataType == 13: + if signalDataType == 13: return 'H' else: return 'I' @@ -571,7 +579,7 @@ def Format(self, info): elif self.type == 'Inv': return '{}s'.format(self.nBytes(info)) else: - print('Not found channel type') + warn('Not found channel type') def CFormat(self, info): """ channel data C format struct object @@ -1060,7 +1068,7 @@ def datatypeformat4(signalDataType, numberOfBytes): C format used by fread to read channel raw data """ - if signalDataType in (0, 1): # unsigned int + if signalDataType == 0: # unsigned int if numberOfBytes == 1: dataType = 'B' elif numberOfBytes == 2: @@ -1071,8 +1079,22 @@ def datatypeformat4(signalDataType, numberOfBytes): dataType = 'Q' else: dataType = '{}s'.format(numberOfBytes) + endian = '<' - elif signalDataType in (2, 3): # signed int + elif signalDataType == 1: # unsigned int + if numberOfBytes == 1: + dataType = 'B' + elif numberOfBytes == 2: + dataType = 'H' + elif numberOfBytes <= 4: + dataType = 'I' + elif numberOfBytes <= 8: + dataType = 'Q' + else: + dataType = '{}s'.format(numberOfBytes) + endian = '>' + + elif signalDataType == 2: # signed int if numberOfBytes == 1: dataType = 'b' elif numberOfBytes == 2: @@ -1083,26 +1105,55 @@ def datatypeformat4(signalDataType, numberOfBytes): dataType = 'q' else: warn('Unsupported number of bytes for signed int {}'.format(signalDataType)) + endian = '<' - elif signalDataType in (4, 5): # floating point + elif signalDataType == 3: # signed int + if numberOfBytes == 1: + dataType = 'b' + elif numberOfBytes == 2: + dataType = 'h' + elif numberOfBytes <= 4: + dataType = 'i' + elif numberOfBytes <= 8: + dataType = 'q' + else: + warn('Unsupported number of bytes for signed int {}'.format(signalDataType)) + endian = '>' + + elif signalDataType == 4: # floating point if numberOfBytes == 4: dataType = 'f' elif numberOfBytes == 8: dataType = 'd' else: warn('Unsupported number of bytes for floating point {}'.format(signalDataType)) + endian = '<' + + elif signalDataType == 5: # floating point + if numberOfBytes == 4: + dataType = 'f' + elif numberOfBytes == 8: + dataType = 'd' + else: + warn('Unsupported number of bytes for floating point {}'.format(signalDataType)) + endian = '>' - elif signalDataType in (6, 7, 8, 9, 10, 11, 12): # string/bytes + elif signalDataType in (6, 7, 10, 11, 12): # string/bytes dataType = '{}s'.format(numberOfBytes) + endian = '' + + elif signalDataType == 8: # UTF16 string/bytes + dataType = '{}s'.format(numberOfBytes) + endian = '<' + + elif signalDataType == 9: # UTF16 string/bytes + dataType = '{}s'.format(numberOfBytes) + endian = '>' + else: warn('Unsupported Signal Data Type {} {}'.format(signalDataType, numberOfBytes)) - # deal with byte order - if signalDataType in (0, 2, 4, 8): # low endian - dataType = '<{}'.format(dataType) - elif signalDataType in (1, 3, 5, 9): # big endian - dataType = '>{}'.format(dataType) - return dataType + return endian, dataType class Channel3: From 704758200fb72e72e1c1627619bd0ce833816385 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Mon, 17 Sep 2018 22:11:31 +0200 Subject: [PATCH 04/61] read_channels_from_bytes_fallback modification for arrays reading --- mdfreader/mdf4reader.py | 46 ++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index 07d5d1c..e00b7b8 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -888,8 +888,7 @@ def readRecordBuf(self, buf, info, channelSet=None): for Channel in self: # list of channel classes from channelSet if Channel.name in channelSet and not Channel.VLSD_CG_Flag: temp[Channel.name] = \ - Channel.CFormat(info).unpack(buf[Channel.posByteBeg(info):\ - Channel.posByteEnd(info)])[0] + Channel.CFormat(info).unpack(buf[Channel.posByteBeg(info):Channel.posByteEnd(info)])[0] return temp # returns dictionary of channel with its corresponding values def initialise_recarray(self, info, channelSet, nrecords, dtype=None, channels_indexes=None): @@ -1030,27 +1029,32 @@ def signedInt(temp, extension): B.frombytes(bytes(bita)) record_bit_size = self.CGrecordLength * 8 for chan in channels_indexes: - temp = [B[self[chan].posBitBeg(info) + record_bit_size * i: - self[chan].posBitEnd(info) + record_bit_size * i] - for i in range(nrecords)] - nbytes = len(temp[0].tobytes()) signalDataType = self[chan].signalDataType(info) nBytes = self[chan].nBytes(info) - if not nbytes == nBytes and \ - signalDataType not in (6, 7, 8, 9, 10, 11, 12): # not Ctype byte length - byte = bitarray(8 * (nBytes - nbytes), endian='little') - byte.setall(False) - if signalDataType not in (2, 3): # not signed integer - for i in range(nrecords): # extend data of bytes to match numpy requirement - temp[i].extend(byte) - else: # signed integer (two's complement), keep sign bit and extend with bytes - temp = signedInt(temp, byte) - nTrailBits = nBytes*8 - self[chan].bitCount(info) - if signalDataType in (2, 3) and \ - nbytes == nBytes and \ - nTrailBits > 0: # Ctype byte length but signed integer - trailBits = bitarray(nTrailBits, endian='little') - temp = signedInt(temp, trailBits) + if not self[chan].type in ('CA', 'NestCA'): + temp = [B[self[chan].posBitBeg(info) + record_bit_size * i: + self[chan].posBitEnd(info) + record_bit_size * i] + for i in range(nrecords)] + nbytes = len(temp[0].tobytes()) + if not nbytes == nBytes and \ + signalDataType not in (6, 7, 8, 9, 10, 11, 12): # not Ctype byte length + byte = bitarray(8 * (nBytes - nbytes), endian='little') + byte.setall(False) + if signalDataType not in (2, 3): # not signed integer + for i in range(nrecords): # extend data of bytes to match numpy requirement + temp[i].extend(byte) + else: # signed integer (two's complement), keep sign bit and extend with bytes + temp = signedInt(temp, byte) + nTrailBits = nBytes*8 - self[chan].bitCount(info) + if signalDataType in (2, 3) and \ + nbytes == nBytes and \ + nTrailBits > 0: # Ctype byte length but signed integer + trailBits = bitarray(nTrailBits, endian='little') + temp = signedInt(temp, trailBits) + else: # Channel Array + temp = [B[self[chan].posBitBeg(info) + record_bit_size * i: + self[chan].posBitBeg(info) + 8 * nBytes + record_bit_size * i] + for i in range(nrecords)] if 's' not in self[chan].Format(info): CFormat = self[chan].CFormat(info) if ('>' in self[chan].dataFormat(info) and byteorder == 'little') or \ From c8290b664c406c1aa78f3ce9e1227da95dd4ee53 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Tue, 18 Sep 2018 22:37:17 +0200 Subject: [PATCH 05/61] fixed extension building issues --- setup.cfg | 2 ++ setup.py | 22 ++++++---------------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/setup.cfg b/setup.cfg index 3c6e79c..c25bdbc 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,2 +1,4 @@ [bdist_wheel] universal=1 +[build_ext] +inplace=1 \ No newline at end of file diff --git a/setup.py b/setup.py index d06cf0a..33a1b38 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,9 @@ from warnings import warn try: - from Cython.Distutils import build_ext + from Cython.Build import cythonize + import numpy + ext_modules = cythonize('dataRead', include_path=[numpy.get_include()]) except: # If we couldn't import Cython, use the normal setuptools # and look for a pre-compiled .c file instead of a .pyx file @@ -16,20 +18,6 @@ ext_modules = [Extension("dataRead", ["dataRead.pyx"])] -class CustomBuildExtCommand(build_ext): - """build_ext command for use when numpy headers are needed.""" - def run(self): - - # Import numpy here, only when headers are needed - import numpy - - # Add numpy headers to include_dirs - self.include_dirs.append(numpy.get_include()) - - # Call original build_ext command - build_ext.run(self) - - name = 'mdfreader' version = '2.7.8' @@ -117,13 +105,15 @@ def run(self): entry_points = { 'console_scripts': ['mdfconverter=mdfconverter.mdfconverter:main', ], } - +print(ext_modules) try: # try compiling module with cython or c code setup(name=name, version=version, description=description, long_description=long_description, url=url, author=author, author_email=author_email, license=license, classifiers=classifiers, keywords=keywords, packages=packages, install_requires=install_requires, extras_require=extras_require, entry_points=entry_points, ext_modules=ext_modules) except: # without Cython + import sys + print("Unexpected error:", sys.exc_info()) extras_require.pop('experimental') install_requires.append('bitarray') # replaces cython requirement by bitarray setup(name=name, version=version, description=description, long_description=long_description, From 620d692a44ef323233c35e9e0d8fd79dbd56aee3 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Fri, 21 Sep 2018 23:04:38 +0200 Subject: [PATCH 06/61] fixed extension building issues --- dataRead.pyx | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/dataRead.pyx b/dataRead.pyx index 1d00794..475a673 100644 --- a/dataRead.pyx +++ b/dataRead.pyx @@ -64,13 +64,13 @@ def dataRead(bytes tmp, unsigned short bitCount, else: # swap bytes return dataReadDouble(bita, RecordFormat, numberOfRecords, record_byte_size, posByteBeg, 1) - elif signalDataType in (0, 1, 13) and bitCount <= 8: # unsigned char + elif signalDataType in (0, 1, 13) and bitCount + bitOffset <= 8: # unsigned char return dataReadUChar(bita, RecordFormat, numberOfRecords, record_byte_size, posByteBeg, bitCount, bitOffset) - elif signalDataType in (2, 3) and bitCount <= 8: # signed char + elif signalDataType in (2, 3) and bitCount + bitOffset <= 8: # signed char return dataReadChar(bita, RecordFormat, numberOfRecords, record_byte_size, posByteBeg, bitCount, bitOffset) - elif signalDataType in (0, 1, 13, 14) and bitCount <=16: # unsigned short + elif signalDataType in (0, 1, 13, 14) and bitCount + bitOffset <=16: # unsigned short if (byteorder == 'little' and signalDataType == 0) or \ (byteorder == 'big' and signalDataType == 1): return dataReadUShort(bita, RecordFormat, numberOfRecords, @@ -78,7 +78,7 @@ def dataRead(bytes tmp, unsigned short bitCount, else: # swap bytes return dataReadUShort(bita, RecordFormat, numberOfRecords, record_byte_size, posByteBeg, bitCount, bitOffset, 1) - elif signalDataType in (2, 3) and bitCount <= 16: # signed short + elif signalDataType in (2, 3) and bitCount + bitOffset <= 16: # signed short if (byteorder == 'little' and signalDataType == 2) or \ (byteorder == 'big' and signalDataType == 3): return dataReadShort(bita, RecordFormat, numberOfRecords, @@ -86,7 +86,7 @@ def dataRead(bytes tmp, unsigned short bitCount, else: # swap bytes return dataReadShort(bita, RecordFormat, numberOfRecords, record_byte_size, posByteBeg, bitCount, bitOffset, 1) - elif signalDataType in (0, 1, 14) and bitCount <=32: # unsigned int + elif signalDataType in (0, 1, 14) and bitCount + bitOffset <=32: # unsigned int if (byteorder == 'little' and signalDataType == 0) or \ (byteorder == 'big' and signalDataType == 1): return dataReadUInt(bita, RecordFormat, numberOfRecords, @@ -94,7 +94,7 @@ def dataRead(bytes tmp, unsigned short bitCount, else: # swap bytes return dataReadUInt(bita, RecordFormat, numberOfRecords, record_byte_size, posByteBeg, bitCount, bitOffset, 1) - elif signalDataType in (2, 3) and bitCount <= 32: # signed int + elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int if (byteorder == 'little' and signalDataType == 2) or \ (byteorder == 'big' and signalDataType == 3): return dataReadInt(bita, RecordFormat, numberOfRecords, @@ -102,7 +102,7 @@ def dataRead(bytes tmp, unsigned short bitCount, else: # swap bytes return dataReadInt(bita, RecordFormat, numberOfRecords, record_byte_size, posByteBeg, bitCount, bitOffset, 1) - elif signalDataType in (0, 1) and bitCount <=64: # unsigned long long + elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long if (byteorder == 'little' and signalDataType == 0) or \ (byteorder == 'big' and signalDataType == 1): return dataReadULongLong(bita, RecordFormat, numberOfRecords, @@ -110,7 +110,7 @@ def dataRead(bytes tmp, unsigned short bitCount, else: # swap bytes return dataReadULongLong(bita, RecordFormat, numberOfRecords, record_byte_size, posByteBeg, bitCount, bitOffset, 1) - elif signalDataType in (2, 3) and bitCount <= 64: # signed long long + elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long if (byteorder == 'little' and signalDataType == 0) or \ (byteorder == 'big' and signalDataType == 1): return dataReadLongLong(bita, RecordFormat, numberOfRecords, @@ -306,7 +306,7 @@ cdef inline dataReadUInt(const char* bita, str RecordFormat, unsigned long long cdef unsigned char nBytes = 0 cdef char temp4[4] cdef char temp3[3] - if bitCount > 24: + if bitCount + bitOffset > 24: nBytes = 4 else: nBytes = 3 @@ -379,7 +379,7 @@ cdef inline dataReadInt(const char* bita, str RecordFormat, unsigned long long n cdef int signExtend = ((1 << (32 - bitCount)) - 1) << bitCount cdef char temp4[4] cdef char temp3[3] - if bitCount > 24: + if bitCount + bitOffset > 24: nBytes = 4 else: nBytes = 3 @@ -457,12 +457,12 @@ cdef inline dataReadULongLong(const char* bita, str RecordFormat, unsigned long cdef unsigned long long i cdef unsigned long long mask = ((1 << bitCount) - 1) cdef unsigned long long temp8byte = 0 - cdef unsigned char nBytes = bitCount // 8 + cdef unsigned char nBytes = bitCount + bitOffset // 8 cdef char temp8[8] cdef char temp7[7] cdef char temp6[6] cdef char temp5[5] - if bitCount % 8 > 0: + if bitCount + bitOffset % 8 > 0: nBytes += 1 if bitCount == 64: for i in range(numberOfRecords): @@ -573,7 +573,7 @@ cdef inline dataReadLongLong(const char* bita, str RecordFormat, unsigned long l cdef unsigned long long i cdef long long mask = ((1 << bitCount) - 1) cdef long long temp8byte = 0 - cdef unsigned char nBytes = bitCount // 8 + cdef unsigned char nBytes = bitCount + bitOffset // 8 cdef long signBit = 0 cdef long long signBitMask = (1 << (bitCount-1)) cdef long long signExtend = ((1 << (64 - bitCount)) - 1) << bitCount @@ -581,7 +581,7 @@ cdef inline dataReadLongLong(const char* bita, str RecordFormat, unsigned long l cdef char temp7[7] cdef char temp6[6] cdef char temp5[5] - if bitCount % 8 > 0: + if bitCount + bitOffset % 8 > 0: nBytes += 1 if bitCount == 64: for i in range(numberOfRecords): From 469800d0a02b8b8ff4b7a7bfbc0b338e6e12d12f Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Fri, 21 Sep 2018 23:05:08 +0200 Subject: [PATCH 07/61] review nbyte calculation --- dataRead.c | 702 ++++++++++++++++++++++++++++------------------------- 1 file changed, 369 insertions(+), 333 deletions(-) diff --git a/dataRead.c b/dataRead.c index fb47c2d..5d85304 100644 --- a/dataRead.c +++ b/dataRead.c @@ -1,17 +1,4 @@ -/* Generated by Cython 0.28.3 */ - -/* BEGIN: Cython Metadata -{ - "distutils": { - "depends": [], - "name": "dataRead", - "sources": [ - "/home/ratal/workspace/mdfreader/dataRead.pyx" - ] - }, - "module_name": "dataRead" -} -END: Cython Metadata */ +/* Generated by Cython 0.28.4 */ #define PY_SSIZE_T_CLEAN #include "Python.h" @@ -20,7 +7,7 @@ END: Cython Metadata */ #elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) #error Cython requires Python 2.6+ or Python 3.3+. #else -#define CYTHON_ABI "0_28_3" +#define CYTHON_ABI "0_28_4" #define CYTHON_FUTURE_DIVISION 0 #include #ifndef offsetof @@ -845,7 +832,7 @@ typedef struct { } __Pyx_BufFmt_Context; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":730 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":730 * # in Cython to enable them only on the right systems. * * ctypedef npy_int8 int8_t # <<<<<<<<<<<<<< @@ -854,7 +841,7 @@ typedef struct { */ typedef npy_int8 __pyx_t_5numpy_int8_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":731 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":731 * * ctypedef npy_int8 int8_t * ctypedef npy_int16 int16_t # <<<<<<<<<<<<<< @@ -863,7 +850,7 @@ typedef npy_int8 __pyx_t_5numpy_int8_t; */ typedef npy_int16 __pyx_t_5numpy_int16_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":732 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":732 * ctypedef npy_int8 int8_t * ctypedef npy_int16 int16_t * ctypedef npy_int32 int32_t # <<<<<<<<<<<<<< @@ -872,7 +859,7 @@ typedef npy_int16 __pyx_t_5numpy_int16_t; */ typedef npy_int32 __pyx_t_5numpy_int32_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":733 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":733 * ctypedef npy_int16 int16_t * ctypedef npy_int32 int32_t * ctypedef npy_int64 int64_t # <<<<<<<<<<<<<< @@ -881,7 +868,7 @@ typedef npy_int32 __pyx_t_5numpy_int32_t; */ typedef npy_int64 __pyx_t_5numpy_int64_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":737 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":737 * #ctypedef npy_int128 int128_t * * ctypedef npy_uint8 uint8_t # <<<<<<<<<<<<<< @@ -890,7 +877,7 @@ typedef npy_int64 __pyx_t_5numpy_int64_t; */ typedef npy_uint8 __pyx_t_5numpy_uint8_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":738 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":738 * * ctypedef npy_uint8 uint8_t * ctypedef npy_uint16 uint16_t # <<<<<<<<<<<<<< @@ -899,7 +886,7 @@ typedef npy_uint8 __pyx_t_5numpy_uint8_t; */ typedef npy_uint16 __pyx_t_5numpy_uint16_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":739 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":739 * ctypedef npy_uint8 uint8_t * ctypedef npy_uint16 uint16_t * ctypedef npy_uint32 uint32_t # <<<<<<<<<<<<<< @@ -908,7 +895,7 @@ typedef npy_uint16 __pyx_t_5numpy_uint16_t; */ typedef npy_uint32 __pyx_t_5numpy_uint32_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":740 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":740 * ctypedef npy_uint16 uint16_t * ctypedef npy_uint32 uint32_t * ctypedef npy_uint64 uint64_t # <<<<<<<<<<<<<< @@ -917,7 +904,7 @@ typedef npy_uint32 __pyx_t_5numpy_uint32_t; */ typedef npy_uint64 __pyx_t_5numpy_uint64_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":744 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":744 * #ctypedef npy_uint128 uint128_t * * ctypedef npy_float32 float32_t # <<<<<<<<<<<<<< @@ -926,7 +913,7 @@ typedef npy_uint64 __pyx_t_5numpy_uint64_t; */ typedef npy_float32 __pyx_t_5numpy_float32_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":745 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":745 * * ctypedef npy_float32 float32_t * ctypedef npy_float64 float64_t # <<<<<<<<<<<<<< @@ -935,7 +922,7 @@ typedef npy_float32 __pyx_t_5numpy_float32_t; */ typedef npy_float64 __pyx_t_5numpy_float64_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":754 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":754 * # The int types are mapped a bit surprising -- * # numpy.int corresponds to 'l' and numpy.long to 'q' * ctypedef npy_long int_t # <<<<<<<<<<<<<< @@ -944,7 +931,7 @@ typedef npy_float64 __pyx_t_5numpy_float64_t; */ typedef npy_long __pyx_t_5numpy_int_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":755 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":755 * # numpy.int corresponds to 'l' and numpy.long to 'q' * ctypedef npy_long int_t * ctypedef npy_longlong long_t # <<<<<<<<<<<<<< @@ -953,7 +940,7 @@ typedef npy_long __pyx_t_5numpy_int_t; */ typedef npy_longlong __pyx_t_5numpy_long_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":756 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":756 * ctypedef npy_long int_t * ctypedef npy_longlong long_t * ctypedef npy_longlong longlong_t # <<<<<<<<<<<<<< @@ -962,7 +949,7 @@ typedef npy_longlong __pyx_t_5numpy_long_t; */ typedef npy_longlong __pyx_t_5numpy_longlong_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":758 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":758 * ctypedef npy_longlong longlong_t * * ctypedef npy_ulong uint_t # <<<<<<<<<<<<<< @@ -971,7 +958,7 @@ typedef npy_longlong __pyx_t_5numpy_longlong_t; */ typedef npy_ulong __pyx_t_5numpy_uint_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":759 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":759 * * ctypedef npy_ulong uint_t * ctypedef npy_ulonglong ulong_t # <<<<<<<<<<<<<< @@ -980,7 +967,7 @@ typedef npy_ulong __pyx_t_5numpy_uint_t; */ typedef npy_ulonglong __pyx_t_5numpy_ulong_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":760 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":760 * ctypedef npy_ulong uint_t * ctypedef npy_ulonglong ulong_t * ctypedef npy_ulonglong ulonglong_t # <<<<<<<<<<<<<< @@ -989,7 +976,7 @@ typedef npy_ulonglong __pyx_t_5numpy_ulong_t; */ typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":762 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":762 * ctypedef npy_ulonglong ulonglong_t * * ctypedef npy_intp intp_t # <<<<<<<<<<<<<< @@ -998,7 +985,7 @@ typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t; */ typedef npy_intp __pyx_t_5numpy_intp_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":763 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":763 * * ctypedef npy_intp intp_t * ctypedef npy_uintp uintp_t # <<<<<<<<<<<<<< @@ -1007,7 +994,7 @@ typedef npy_intp __pyx_t_5numpy_intp_t; */ typedef npy_uintp __pyx_t_5numpy_uintp_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":765 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":765 * ctypedef npy_uintp uintp_t * * ctypedef npy_double float_t # <<<<<<<<<<<<<< @@ -1016,7 +1003,7 @@ typedef npy_uintp __pyx_t_5numpy_uintp_t; */ typedef npy_double __pyx_t_5numpy_float_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":766 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":766 * * ctypedef npy_double float_t * ctypedef npy_double double_t # <<<<<<<<<<<<<< @@ -1025,7 +1012,7 @@ typedef npy_double __pyx_t_5numpy_float_t; */ typedef npy_double __pyx_t_5numpy_double_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":767 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":767 * ctypedef npy_double float_t * ctypedef npy_double double_t * ctypedef npy_longdouble longdouble_t # <<<<<<<<<<<<<< @@ -1060,7 +1047,7 @@ static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(do /*--- Type declarations ---*/ -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":769 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":769 * ctypedef npy_longdouble longdouble_t * * ctypedef npy_cfloat cfloat_t # <<<<<<<<<<<<<< @@ -1069,7 +1056,7 @@ static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(do */ typedef npy_cfloat __pyx_t_5numpy_cfloat_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":770 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":770 * * ctypedef npy_cfloat cfloat_t * ctypedef npy_cdouble cdouble_t # <<<<<<<<<<<<<< @@ -1078,7 +1065,7 @@ typedef npy_cfloat __pyx_t_5numpy_cfloat_t; */ typedef npy_cdouble __pyx_t_5numpy_cdouble_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":771 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":771 * ctypedef npy_cfloat cfloat_t * ctypedef npy_cdouble cdouble_t * ctypedef npy_clongdouble clongdouble_t # <<<<<<<<<<<<<< @@ -1087,7 +1074,7 @@ typedef npy_cdouble __pyx_t_5numpy_cdouble_t; */ typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t; -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":773 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":773 * ctypedef npy_clongdouble clongdouble_t * * ctypedef npy_cdouble complex_t # <<<<<<<<<<<<<< @@ -1317,6 +1304,12 @@ static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject #define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) #endif +/* None.proto */ +static CYTHON_INLINE long __Pyx_div_long(long, long); + +/* None.proto */ +static CYTHON_INLINE long __Pyx_mod_long(long, long); + /* SetItemInt.proto */ #define __Pyx_SetItemInt(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ @@ -2269,7 +2262,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadDouble(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< * record_byte_size, posByteBeg, 1) - * elif signalDataType in (0, 1, 13) and bitCount <= 8: # unsigned char + * elif signalDataType in (0, 1, 13) and bitCount + bitOffset <= 8: # unsigned char */ /*else*/ { __Pyx_XDECREF(__pyx_r); @@ -2278,7 +2271,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadDouble(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, 1) # <<<<<<<<<<<<<< - * elif signalDataType in (0, 1, 13) and bitCount <= 8: # unsigned char + * elif signalDataType in (0, 1, 13) and bitCount + bitOffset <= 8: # unsigned char * return dataReadUChar(bita, RecordFormat, numberOfRecords, */ __pyx_t_5 = __pyx_f_8dataRead_dataReadDouble(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 65, __pyx_L1_error) @@ -2300,7 +2293,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":67 * return dataReadDouble(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, 1) - * elif signalDataType in (0, 1, 13) and bitCount <= 8: # unsigned char # <<<<<<<<<<<<<< + * elif signalDataType in (0, 1, 13) and bitCount + bitOffset <= 8: # unsigned char # <<<<<<<<<<<<<< * return dataReadUChar(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset) */ @@ -2320,25 +2313,25 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_2; goto __pyx_L22_bool_binop_done; } - __pyx_t_2 = ((__pyx_v_bitCount <= 8) != 0); + __pyx_t_2 = (((__pyx_v_bitCount + __pyx_v_bitOffset) <= 8) != 0); __pyx_t_3 = __pyx_t_2; __pyx_L22_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":68 * record_byte_size, posByteBeg, 1) - * elif signalDataType in (0, 1, 13) and bitCount <= 8: # unsigned char + * elif signalDataType in (0, 1, 13) and bitCount + bitOffset <= 8: # unsigned char * return dataReadUChar(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (2, 3) and bitCount <= 8: # signed char + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 8: # signed char */ __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":69 - * elif signalDataType in (0, 1, 13) and bitCount <= 8: # unsigned char + * elif signalDataType in (0, 1, 13) and bitCount + bitOffset <= 8: # unsigned char * return dataReadUChar(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset) # <<<<<<<<<<<<<< - * elif signalDataType in (2, 3) and bitCount <= 8: # signed char + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 8: # signed char * return dataReadChar(bita, RecordFormat, numberOfRecords, */ __pyx_t_5 = __pyx_f_8dataRead_dataReadUChar(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 68, __pyx_L1_error) @@ -2350,7 +2343,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":67 * return dataReadDouble(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, 1) - * elif signalDataType in (0, 1, 13) and bitCount <= 8: # unsigned char # <<<<<<<<<<<<<< + * elif signalDataType in (0, 1, 13) and bitCount + bitOffset <= 8: # unsigned char # <<<<<<<<<<<<<< * return dataReadUChar(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset) */ @@ -2359,7 +2352,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":70 * return dataReadUChar(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (2, 3) and bitCount <= 8: # signed char # <<<<<<<<<<<<<< + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 8: # signed char # <<<<<<<<<<<<<< * return dataReadChar(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset) */ @@ -2378,25 +2371,25 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_4; goto __pyx_L24_bool_binop_done; } - __pyx_t_4 = ((__pyx_v_bitCount <= 8) != 0); + __pyx_t_4 = (((__pyx_v_bitCount + __pyx_v_bitOffset) <= 8) != 0); __pyx_t_3 = __pyx_t_4; __pyx_L24_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":71 * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (2, 3) and bitCount <= 8: # signed char + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 8: # signed char * return dataReadChar(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (0, 1, 13, 14) and bitCount <=16: # unsigned short + * elif signalDataType in (0, 1, 13, 14) and bitCount + bitOffset <=16: # unsigned short */ __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":72 - * elif signalDataType in (2, 3) and bitCount <= 8: # signed char + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 8: # signed char * return dataReadChar(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset) # <<<<<<<<<<<<<< - * elif signalDataType in (0, 1, 13, 14) and bitCount <=16: # unsigned short + * elif signalDataType in (0, 1, 13, 14) and bitCount + bitOffset <=16: # unsigned short * if (byteorder == 'little' and signalDataType == 0) or \ */ __pyx_t_5 = __pyx_f_8dataRead_dataReadChar(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 71, __pyx_L1_error) @@ -2408,7 +2401,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":70 * return dataReadUChar(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (2, 3) and bitCount <= 8: # signed char # <<<<<<<<<<<<<< + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 8: # signed char # <<<<<<<<<<<<<< * return dataReadChar(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset) */ @@ -2417,7 +2410,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":73 * return dataReadChar(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (0, 1, 13, 14) and bitCount <=16: # unsigned short # <<<<<<<<<<<<<< + * elif signalDataType in (0, 1, 13, 14) and bitCount + bitOffset <=16: # unsigned short # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): */ @@ -2438,14 +2431,14 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_2; goto __pyx_L26_bool_binop_done; } - __pyx_t_2 = ((__pyx_v_bitCount <= 16) != 0); + __pyx_t_2 = (((__pyx_v_bitCount + __pyx_v_bitOffset) <= 16) != 0); __pyx_t_3 = __pyx_t_2; __pyx_L26_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":74 * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (0, 1, 13, 14) and bitCount <=16: # unsigned short + * elif signalDataType in (0, 1, 13, 14) and bitCount + bitOffset <=16: # unsigned short * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadUShort(bita, RecordFormat, numberOfRecords, @@ -2467,7 +2460,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L30_next_or:; /* "dataRead.pyx":75 - * elif signalDataType in (0, 1, 13, 14) and bitCount <=16: # unsigned short + * elif signalDataType in (0, 1, 13, 14) and bitCount + bitOffset <=16: # unsigned short * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): # <<<<<<<<<<<<<< * return dataReadUShort(bita, RecordFormat, numberOfRecords, @@ -2488,7 +2481,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":74 * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (0, 1, 13, 14) and bitCount <=16: # unsigned short + * elif signalDataType in (0, 1, 13, 14) and bitCount + bitOffset <=16: # unsigned short * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadUShort(bita, RecordFormat, numberOfRecords, @@ -2519,7 +2512,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":74 * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (0, 1, 13, 14) and bitCount <=16: # unsigned short + * elif signalDataType in (0, 1, 13, 14) and bitCount + bitOffset <=16: # unsigned short * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadUShort(bita, RecordFormat, numberOfRecords, @@ -2531,7 +2524,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadUShort(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount <= 16: # signed short + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 16: # signed short */ /*else*/ { __Pyx_XDECREF(__pyx_r); @@ -2540,7 +2533,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadUShort(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, 1) # <<<<<<<<<<<<<< - * elif signalDataType in (2, 3) and bitCount <= 16: # signed short + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 16: # signed short * if (byteorder == 'little' and signalDataType == 2) or \ */ __pyx_t_5 = __pyx_f_8dataRead_dataReadUShort(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 79, __pyx_L1_error) @@ -2553,7 +2546,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":73 * return dataReadChar(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (0, 1, 13, 14) and bitCount <=16: # unsigned short # <<<<<<<<<<<<<< + * elif signalDataType in (0, 1, 13, 14) and bitCount + bitOffset <=16: # unsigned short # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): */ @@ -2562,7 +2555,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":81 * return dataReadUShort(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount <= 16: # signed short # <<<<<<<<<<<<<< + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 16: # signed short # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 2) or \ * (byteorder == 'big' and signalDataType == 3): */ @@ -2581,14 +2574,14 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_4; goto __pyx_L33_bool_binop_done; } - __pyx_t_4 = ((__pyx_v_bitCount <= 16) != 0); + __pyx_t_4 = (((__pyx_v_bitCount + __pyx_v_bitOffset) <= 16) != 0); __pyx_t_3 = __pyx_t_4; __pyx_L33_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":82 * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount <= 16: # signed short + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 16: # signed short * if (byteorder == 'little' and signalDataType == 2) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 3): * return dataReadShort(bita, RecordFormat, numberOfRecords, @@ -2610,7 +2603,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L37_next_or:; /* "dataRead.pyx":83 - * elif signalDataType in (2, 3) and bitCount <= 16: # signed short + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 16: # signed short * if (byteorder == 'little' and signalDataType == 2) or \ * (byteorder == 'big' and signalDataType == 3): # <<<<<<<<<<<<<< * return dataReadShort(bita, RecordFormat, numberOfRecords, @@ -2631,7 +2624,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":82 * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount <= 16: # signed short + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 16: # signed short * if (byteorder == 'little' and signalDataType == 2) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 3): * return dataReadShort(bita, RecordFormat, numberOfRecords, @@ -2662,7 +2655,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":82 * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount <= 16: # signed short + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 16: # signed short * if (byteorder == 'little' and signalDataType == 2) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 3): * return dataReadShort(bita, RecordFormat, numberOfRecords, @@ -2674,7 +2667,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadShort(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1, 14) and bitCount <=32: # unsigned int + * elif signalDataType in (0, 1, 14) and bitCount + bitOffset <=32: # unsigned int */ /*else*/ { __Pyx_XDECREF(__pyx_r); @@ -2683,7 +2676,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadShort(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, 1) # <<<<<<<<<<<<<< - * elif signalDataType in (0, 1, 14) and bitCount <=32: # unsigned int + * elif signalDataType in (0, 1, 14) and bitCount + bitOffset <=32: # unsigned int * if (byteorder == 'little' and signalDataType == 0) or \ */ __pyx_t_5 = __pyx_f_8dataRead_dataReadShort(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 87, __pyx_L1_error) @@ -2696,7 +2689,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":81 * return dataReadUShort(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount <= 16: # signed short # <<<<<<<<<<<<<< + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 16: # signed short # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 2) or \ * (byteorder == 'big' and signalDataType == 3): */ @@ -2705,7 +2698,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":89 * return dataReadShort(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1, 14) and bitCount <=32: # unsigned int # <<<<<<<<<<<<<< + * elif signalDataType in (0, 1, 14) and bitCount + bitOffset <=32: # unsigned int # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): */ @@ -2725,14 +2718,14 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_2; goto __pyx_L40_bool_binop_done; } - __pyx_t_2 = ((__pyx_v_bitCount <= 32) != 0); + __pyx_t_2 = (((__pyx_v_bitCount + __pyx_v_bitOffset) <= 32) != 0); __pyx_t_3 = __pyx_t_2; __pyx_L40_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":90 * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1, 14) and bitCount <=32: # unsigned int + * elif signalDataType in (0, 1, 14) and bitCount + bitOffset <=32: # unsigned int * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadUInt(bita, RecordFormat, numberOfRecords, @@ -2754,7 +2747,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L44_next_or:; /* "dataRead.pyx":91 - * elif signalDataType in (0, 1, 14) and bitCount <=32: # unsigned int + * elif signalDataType in (0, 1, 14) and bitCount + bitOffset <=32: # unsigned int * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): # <<<<<<<<<<<<<< * return dataReadUInt(bita, RecordFormat, numberOfRecords, @@ -2775,7 +2768,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":90 * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1, 14) and bitCount <=32: # unsigned int + * elif signalDataType in (0, 1, 14) and bitCount + bitOffset <=32: # unsigned int * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadUInt(bita, RecordFormat, numberOfRecords, @@ -2806,7 +2799,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":90 * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1, 14) and bitCount <=32: # unsigned int + * elif signalDataType in (0, 1, 14) and bitCount + bitOffset <=32: # unsigned int * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadUInt(bita, RecordFormat, numberOfRecords, @@ -2818,7 +2811,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadUInt(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount <= 32: # signed int + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int */ /*else*/ { __Pyx_XDECREF(__pyx_r); @@ -2827,7 +2820,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadUInt(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, 1) # <<<<<<<<<<<<<< - * elif signalDataType in (2, 3) and bitCount <= 32: # signed int + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int * if (byteorder == 'little' and signalDataType == 2) or \ */ __pyx_t_5 = __pyx_f_8dataRead_dataReadUInt(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 95, __pyx_L1_error) @@ -2840,7 +2833,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":89 * return dataReadShort(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1, 14) and bitCount <=32: # unsigned int # <<<<<<<<<<<<<< + * elif signalDataType in (0, 1, 14) and bitCount + bitOffset <=32: # unsigned int # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): */ @@ -2849,7 +2842,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":97 * return dataReadUInt(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount <= 32: # signed int # <<<<<<<<<<<<<< + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 2) or \ * (byteorder == 'big' and signalDataType == 3): */ @@ -2868,14 +2861,14 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_4; goto __pyx_L47_bool_binop_done; } - __pyx_t_4 = ((__pyx_v_bitCount <= 32) != 0); + __pyx_t_4 = (((__pyx_v_bitCount + __pyx_v_bitOffset) <= 32) != 0); __pyx_t_3 = __pyx_t_4; __pyx_L47_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":98 * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount <= 32: # signed int + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int * if (byteorder == 'little' and signalDataType == 2) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 3): * return dataReadInt(bita, RecordFormat, numberOfRecords, @@ -2897,7 +2890,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L51_next_or:; /* "dataRead.pyx":99 - * elif signalDataType in (2, 3) and bitCount <= 32: # signed int + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int * if (byteorder == 'little' and signalDataType == 2) or \ * (byteorder == 'big' and signalDataType == 3): # <<<<<<<<<<<<<< * return dataReadInt(bita, RecordFormat, numberOfRecords, @@ -2918,7 +2911,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":98 * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount <= 32: # signed int + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int * if (byteorder == 'little' and signalDataType == 2) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 3): * return dataReadInt(bita, RecordFormat, numberOfRecords, @@ -2949,7 +2942,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":98 * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount <= 32: # signed int + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int * if (byteorder == 'little' and signalDataType == 2) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 3): * return dataReadInt(bita, RecordFormat, numberOfRecords, @@ -2961,7 +2954,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadInt(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1) and bitCount <=64: # unsigned long long + * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long */ /*else*/ { __Pyx_XDECREF(__pyx_r); @@ -2970,7 +2963,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadInt(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, 1) # <<<<<<<<<<<<<< - * elif signalDataType in (0, 1) and bitCount <=64: # unsigned long long + * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long * if (byteorder == 'little' and signalDataType == 0) or \ */ __pyx_t_5 = __pyx_f_8dataRead_dataReadInt(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 103, __pyx_L1_error) @@ -2983,7 +2976,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":97 * return dataReadUInt(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount <= 32: # signed int # <<<<<<<<<<<<<< + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 2) or \ * (byteorder == 'big' and signalDataType == 3): */ @@ -2992,7 +2985,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":105 * return dataReadInt(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1) and bitCount <=64: # unsigned long long # <<<<<<<<<<<<<< + * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): */ @@ -3011,14 +3004,14 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_2; goto __pyx_L54_bool_binop_done; } - __pyx_t_2 = ((__pyx_v_bitCount <= 64) != 0); + __pyx_t_2 = (((__pyx_v_bitCount + __pyx_v_bitOffset) <= 64) != 0); __pyx_t_3 = __pyx_t_2; __pyx_L54_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":106 * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1) and bitCount <=64: # unsigned long long + * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadULongLong(bita, RecordFormat, numberOfRecords, @@ -3040,7 +3033,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L58_next_or:; /* "dataRead.pyx":107 - * elif signalDataType in (0, 1) and bitCount <=64: # unsigned long long + * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): # <<<<<<<<<<<<<< * return dataReadULongLong(bita, RecordFormat, numberOfRecords, @@ -3061,7 +3054,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":106 * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1) and bitCount <=64: # unsigned long long + * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadULongLong(bita, RecordFormat, numberOfRecords, @@ -3092,7 +3085,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":106 * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1) and bitCount <=64: # unsigned long long + * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadULongLong(bita, RecordFormat, numberOfRecords, @@ -3104,7 +3097,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadULongLong(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount <= 64: # signed long long + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long */ /*else*/ { __Pyx_XDECREF(__pyx_r); @@ -3113,7 +3106,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadULongLong(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, 1) # <<<<<<<<<<<<<< - * elif signalDataType in (2, 3) and bitCount <= 64: # signed long long + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long * if (byteorder == 'little' and signalDataType == 0) or \ */ __pyx_t_5 = __pyx_f_8dataRead_dataReadULongLong(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 111, __pyx_L1_error) @@ -3126,7 +3119,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":105 * return dataReadInt(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1) and bitCount <=64: # unsigned long long # <<<<<<<<<<<<<< + * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): */ @@ -3135,7 +3128,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":113 * return dataReadULongLong(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount <= 64: # signed long long # <<<<<<<<<<<<<< + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): */ @@ -3154,14 +3147,14 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_4; goto __pyx_L61_bool_binop_done; } - __pyx_t_4 = ((__pyx_v_bitCount <= 64) != 0); + __pyx_t_4 = (((__pyx_v_bitCount + __pyx_v_bitOffset) <= 64) != 0); __pyx_t_3 = __pyx_t_4; __pyx_L61_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":114 * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount <= 64: # signed long long + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadLongLong(bita, RecordFormat, numberOfRecords, @@ -3183,7 +3176,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L65_next_or:; /* "dataRead.pyx":115 - * elif signalDataType in (2, 3) and bitCount <= 64: # signed long long + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): # <<<<<<<<<<<<<< * return dataReadLongLong(bita, RecordFormat, numberOfRecords, @@ -3204,7 +3197,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":114 * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount <= 64: # signed long long + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadLongLong(bita, RecordFormat, numberOfRecords, @@ -3235,7 +3228,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":114 * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount <= 64: # signed long long + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadLongLong(bita, RecordFormat, numberOfRecords, @@ -3269,7 +3262,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":113 * return dataReadULongLong(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount <= 64: # signed long long # <<<<<<<<<<<<<< + * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): */ @@ -5653,16 +5646,16 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ /* "dataRead.pyx":309 * cdef char temp4[4] * cdef char temp3[3] - * if bitCount > 24: # <<<<<<<<<<<<<< + * if bitCount + bitOffset > 24: # <<<<<<<<<<<<<< * nBytes = 4 * else: */ - __pyx_t_6 = ((__pyx_v_bitCount > 24) != 0); + __pyx_t_6 = (((__pyx_v_bitCount + __pyx_v_bitOffset) > 24) != 0); if (__pyx_t_6) { /* "dataRead.pyx":310 * cdef char temp3[3] - * if bitCount > 24: + * if bitCount + bitOffset > 24: * nBytes = 4 # <<<<<<<<<<<<<< * else: * nBytes = 3 @@ -5672,7 +5665,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ /* "dataRead.pyx":309 * cdef char temp4[4] * cdef char temp3[3] - * if bitCount > 24: # <<<<<<<<<<<<<< + * if bitCount + bitOffset > 24: # <<<<<<<<<<<<<< * nBytes = 4 * else: */ @@ -6472,16 +6465,16 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v /* "dataRead.pyx":382 * cdef char temp4[4] * cdef char temp3[3] - * if bitCount > 24: # <<<<<<<<<<<<<< + * if bitCount + bitOffset > 24: # <<<<<<<<<<<<<< * nBytes = 4 * else: */ - __pyx_t_6 = ((__pyx_v_bitCount > 24) != 0); + __pyx_t_6 = (((__pyx_v_bitCount + __pyx_v_bitOffset) > 24) != 0); if (__pyx_t_6) { /* "dataRead.pyx":383 * cdef char temp3[3] - * if bitCount > 24: + * if bitCount + bitOffset > 24: * nBytes = 4 # <<<<<<<<<<<<<< * else: * nBytes = 3 @@ -6491,7 +6484,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v /* "dataRead.pyx":382 * cdef char temp4[4] * cdef char temp3[3] - * if bitCount > 24: # <<<<<<<<<<<<<< + * if bitCount + bitOffset > 24: # <<<<<<<<<<<<<< * nBytes = 4 * else: */ @@ -7390,7 +7383,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ * cdef unsigned long long i * cdef unsigned long long mask = ((1 << bitCount) - 1) # <<<<<<<<<<<<<< * cdef unsigned long long temp8byte = 0 - * cdef unsigned char nBytes = bitCount // 8 + * cdef unsigned char nBytes = bitCount + bitOffset // 8 */ __pyx_v_mask = ((1 << __pyx_v_bitCount) - 1); @@ -7398,7 +7391,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ * cdef unsigned long long i * cdef unsigned long long mask = ((1 << bitCount) - 1) * cdef unsigned long long temp8byte = 0 # <<<<<<<<<<<<<< - * cdef unsigned char nBytes = bitCount // 8 + * cdef unsigned char nBytes = bitCount + bitOffset // 8 * cdef char temp8[8] */ __pyx_v_temp8byte = 0; @@ -7406,25 +7399,25 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ /* "dataRead.pyx":460 * cdef unsigned long long mask = ((1 << bitCount) - 1) * cdef unsigned long long temp8byte = 0 - * cdef unsigned char nBytes = bitCount // 8 # <<<<<<<<<<<<<< + * cdef unsigned char nBytes = bitCount + bitOffset // 8 # <<<<<<<<<<<<<< * cdef char temp8[8] * cdef char temp7[7] */ - __pyx_v_nBytes = (__pyx_v_bitCount / 8); + __pyx_v_nBytes = (__pyx_v_bitCount + __Pyx_div_long(__pyx_v_bitOffset, 8)); /* "dataRead.pyx":465 * cdef char temp6[6] * cdef char temp5[5] - * if bitCount % 8 > 0: # <<<<<<<<<<<<<< + * if bitCount + bitOffset % 8 > 0: # <<<<<<<<<<<<<< * nBytes += 1 * if bitCount == 64: */ - __pyx_t_6 = (((__pyx_v_bitCount % 8) > 0) != 0); + __pyx_t_6 = (((__pyx_v_bitCount + __Pyx_mod_long(__pyx_v_bitOffset, 8)) > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":466 * cdef char temp5[5] - * if bitCount % 8 > 0: + * if bitCount + bitOffset % 8 > 0: * nBytes += 1 # <<<<<<<<<<<<<< * if bitCount == 64: * for i in range(numberOfRecords): @@ -7434,14 +7427,14 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ /* "dataRead.pyx":465 * cdef char temp6[6] * cdef char temp5[5] - * if bitCount % 8 > 0: # <<<<<<<<<<<<<< + * if bitCount + bitOffset % 8 > 0: # <<<<<<<<<<<<<< * nBytes += 1 * if bitCount == 64: */ } /* "dataRead.pyx":467 - * if bitCount % 8 > 0: + * if bitCount + bitOffset % 8 > 0: * nBytes += 1 * if bitCount == 64: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): @@ -7554,7 +7547,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ } /* "dataRead.pyx":467 - * if bitCount % 8 > 0: + * if bitCount + bitOffset % 8 > 0: * nBytes += 1 * if bitCount == 64: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): @@ -8662,7 +8655,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ * cdef unsigned long long i * cdef long long mask = ((1 << bitCount) - 1) # <<<<<<<<<<<<<< * cdef long long temp8byte = 0 - * cdef unsigned char nBytes = bitCount // 8 + * cdef unsigned char nBytes = bitCount + bitOffset // 8 */ __pyx_v_mask = ((1 << __pyx_v_bitCount) - 1); @@ -8670,7 +8663,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ * cdef unsigned long long i * cdef long long mask = ((1 << bitCount) - 1) * cdef long long temp8byte = 0 # <<<<<<<<<<<<<< - * cdef unsigned char nBytes = bitCount // 8 + * cdef unsigned char nBytes = bitCount + bitOffset // 8 * cdef long signBit = 0 */ __pyx_v_temp8byte = 0; @@ -8678,15 +8671,15 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ /* "dataRead.pyx":576 * cdef long long mask = ((1 << bitCount) - 1) * cdef long long temp8byte = 0 - * cdef unsigned char nBytes = bitCount // 8 # <<<<<<<<<<<<<< + * cdef unsigned char nBytes = bitCount + bitOffset // 8 # <<<<<<<<<<<<<< * cdef long signBit = 0 * cdef long long signBitMask = (1 << (bitCount-1)) */ - __pyx_v_nBytes = (__pyx_v_bitCount / 8); + __pyx_v_nBytes = (__pyx_v_bitCount + __Pyx_div_long(__pyx_v_bitOffset, 8)); /* "dataRead.pyx":577 * cdef long long temp8byte = 0 - * cdef unsigned char nBytes = bitCount // 8 + * cdef unsigned char nBytes = bitCount + bitOffset // 8 * cdef long signBit = 0 # <<<<<<<<<<<<<< * cdef long long signBitMask = (1 << (bitCount-1)) * cdef long long signExtend = ((1 << (64 - bitCount)) - 1) << bitCount @@ -8694,7 +8687,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_v_signBit = 0; /* "dataRead.pyx":578 - * cdef unsigned char nBytes = bitCount // 8 + * cdef unsigned char nBytes = bitCount + bitOffset // 8 * cdef long signBit = 0 * cdef long long signBitMask = (1 << (bitCount-1)) # <<<<<<<<<<<<<< * cdef long long signExtend = ((1 << (64 - bitCount)) - 1) << bitCount @@ -8714,16 +8707,16 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ /* "dataRead.pyx":584 * cdef char temp6[6] * cdef char temp5[5] - * if bitCount % 8 > 0: # <<<<<<<<<<<<<< + * if bitCount + bitOffset % 8 > 0: # <<<<<<<<<<<<<< * nBytes += 1 * if bitCount == 64: */ - __pyx_t_6 = (((__pyx_v_bitCount % 8) > 0) != 0); + __pyx_t_6 = (((__pyx_v_bitCount + __Pyx_mod_long(__pyx_v_bitOffset, 8)) > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":585 * cdef char temp5[5] - * if bitCount % 8 > 0: + * if bitCount + bitOffset % 8 > 0: * nBytes += 1 # <<<<<<<<<<<<<< * if bitCount == 64: * for i in range(numberOfRecords): @@ -8733,14 +8726,14 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ /* "dataRead.pyx":584 * cdef char temp6[6] * cdef char temp5[5] - * if bitCount % 8 > 0: # <<<<<<<<<<<<<< + * if bitCount + bitOffset % 8 > 0: # <<<<<<<<<<<<<< * nBytes += 1 * if bitCount == 64: */ } /* "dataRead.pyx":586 - * if bitCount % 8 > 0: + * if bitCount + bitOffset % 8 > 0: * nBytes += 1 * if bitCount == 64: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): @@ -8853,7 +8846,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ } /* "dataRead.pyx":586 - * if bitCount % 8 > 0: + * if bitCount + bitOffset % 8 > 0: * nBytes += 1 * if bitCount == 64: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): @@ -10492,7 +10485,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *__pyx return __pyx_r; } -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":215 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":215 * # experimental exception made for __getbuffer__ and __releasebuffer__ * # -- the details of this may change. * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<< @@ -10540,7 +10533,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None); __Pyx_GIVEREF(__pyx_v_info->obj); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":222 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":222 * * cdef int i, ndim * cdef int endian_detector = 1 # <<<<<<<<<<<<<< @@ -10549,7 +10542,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P */ __pyx_v_endian_detector = 1; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":223 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":223 * cdef int i, ndim * cdef int endian_detector = 1 * cdef bint little_endian = ((&endian_detector)[0] != 0) # <<<<<<<<<<<<<< @@ -10558,7 +10551,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P */ __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":225 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":225 * cdef bint little_endian = ((&endian_detector)[0] != 0) * * ndim = PyArray_NDIM(self) # <<<<<<<<<<<<<< @@ -10567,7 +10560,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P */ __pyx_v_ndim = PyArray_NDIM(__pyx_v_self); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":227 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":227 * ndim = PyArray_NDIM(self) * * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<< @@ -10581,7 +10574,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P goto __pyx_L4_bool_binop_done; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":228 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":228 * * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): # <<<<<<<<<<<<<< @@ -10592,7 +10585,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_t_1 = __pyx_t_2; __pyx_L4_bool_binop_done:; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":227 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":227 * ndim = PyArray_NDIM(self) * * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<< @@ -10601,7 +10594,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P */ if (unlikely(__pyx_t_1)) { - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":229 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":229 * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<< @@ -10614,7 +10607,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __PYX_ERR(1, 229, __pyx_L1_error) - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":227 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":227 * ndim = PyArray_NDIM(self) * * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<< @@ -10623,7 +10616,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P */ } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":231 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":231 * raise ValueError(u"ndarray is not C contiguous") * * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<< @@ -10637,7 +10630,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P goto __pyx_L7_bool_binop_done; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":232 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":232 * * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): # <<<<<<<<<<<<<< @@ -10648,7 +10641,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_t_1 = __pyx_t_2; __pyx_L7_bool_binop_done:; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":231 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":231 * raise ValueError(u"ndarray is not C contiguous") * * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<< @@ -10657,7 +10650,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P */ if (unlikely(__pyx_t_1)) { - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":233 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":233 * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<< @@ -10670,7 +10663,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __PYX_ERR(1, 233, __pyx_L1_error) - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":231 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":231 * raise ValueError(u"ndarray is not C contiguous") * * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<< @@ -10679,7 +10672,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P */ } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":235 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":235 * raise ValueError(u"ndarray is not Fortran contiguous") * * info.buf = PyArray_DATA(self) # <<<<<<<<<<<<<< @@ -10688,7 +10681,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P */ __pyx_v_info->buf = PyArray_DATA(__pyx_v_self); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":236 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":236 * * info.buf = PyArray_DATA(self) * info.ndim = ndim # <<<<<<<<<<<<<< @@ -10697,7 +10690,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P */ __pyx_v_info->ndim = __pyx_v_ndim; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":237 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":237 * info.buf = PyArray_DATA(self) * info.ndim = ndim * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< @@ -10707,7 +10700,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0); if (__pyx_t_1) { - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":240 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":240 * # Allocate new buffer for strides and shape info. * # This is allocated as one block, strides first. * info.strides = PyObject_Malloc(sizeof(Py_ssize_t) * 2 * ndim) # <<<<<<<<<<<<<< @@ -10716,7 +10709,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P */ __pyx_v_info->strides = ((Py_ssize_t *)PyObject_Malloc((((sizeof(Py_ssize_t)) * 2) * ((size_t)__pyx_v_ndim)))); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":241 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":241 * # This is allocated as one block, strides first. * info.strides = PyObject_Malloc(sizeof(Py_ssize_t) * 2 * ndim) * info.shape = info.strides + ndim # <<<<<<<<<<<<<< @@ -10725,7 +10718,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P */ __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":242 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":242 * info.strides = PyObject_Malloc(sizeof(Py_ssize_t) * 2 * ndim) * info.shape = info.strides + ndim * for i in range(ndim): # <<<<<<<<<<<<<< @@ -10737,7 +10730,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) { __pyx_v_i = __pyx_t_6; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":243 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":243 * info.shape = info.strides + ndim * for i in range(ndim): * info.strides[i] = PyArray_STRIDES(self)[i] # <<<<<<<<<<<<<< @@ -10746,7 +10739,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P */ (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":244 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":244 * for i in range(ndim): * info.strides[i] = PyArray_STRIDES(self)[i] * info.shape[i] = PyArray_DIMS(self)[i] # <<<<<<<<<<<<<< @@ -10756,7 +10749,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]); } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":237 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":237 * info.buf = PyArray_DATA(self) * info.ndim = ndim * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< @@ -10766,7 +10759,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P goto __pyx_L9; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":246 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":246 * info.shape[i] = PyArray_DIMS(self)[i] * else: * info.strides = PyArray_STRIDES(self) # <<<<<<<<<<<<<< @@ -10776,7 +10769,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P /*else*/ { __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self)); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":247 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":247 * else: * info.strides = PyArray_STRIDES(self) * info.shape = PyArray_DIMS(self) # <<<<<<<<<<<<<< @@ -10787,7 +10780,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P } __pyx_L9:; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":248 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":248 * info.strides = PyArray_STRIDES(self) * info.shape = PyArray_DIMS(self) * info.suboffsets = NULL # <<<<<<<<<<<<<< @@ -10796,7 +10789,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P */ __pyx_v_info->suboffsets = NULL; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":249 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":249 * info.shape = PyArray_DIMS(self) * info.suboffsets = NULL * info.itemsize = PyArray_ITEMSIZE(self) # <<<<<<<<<<<<<< @@ -10805,7 +10798,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P */ __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":250 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":250 * info.suboffsets = NULL * info.itemsize = PyArray_ITEMSIZE(self) * info.readonly = not PyArray_ISWRITEABLE(self) # <<<<<<<<<<<<<< @@ -10814,7 +10807,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P */ __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0)); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":253 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":253 * * cdef int t * cdef char* f = NULL # <<<<<<<<<<<<<< @@ -10823,7 +10816,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P */ __pyx_v_f = NULL; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":254 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":254 * cdef int t * cdef char* f = NULL * cdef dtype descr = self.descr # <<<<<<<<<<<<<< @@ -10835,7 +10828,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3); __pyx_t_3 = 0; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":257 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":257 * cdef int offset * * info.obj = self # <<<<<<<<<<<<<< @@ -10848,7 +10841,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = ((PyObject *)__pyx_v_self); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":259 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":259 * info.obj = self * * if not PyDataType_HASFIELDS(descr): # <<<<<<<<<<<<<< @@ -10858,7 +10851,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_t_1 = ((!(PyDataType_HASFIELDS(__pyx_v_descr) != 0)) != 0); if (__pyx_t_1) { - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":260 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":260 * * if not PyDataType_HASFIELDS(descr): * t = descr.type_num # <<<<<<<<<<<<<< @@ -10868,7 +10861,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_t_4 = __pyx_v_descr->type_num; __pyx_v_t = __pyx_t_4; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":261 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":261 * if not PyDataType_HASFIELDS(descr): * t = descr.type_num * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< @@ -10888,7 +10881,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P } __pyx_L15_next_or:; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":262 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":262 * t = descr.type_num * if ((descr.byteorder == c'>' and little_endian) or * (descr.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<< @@ -10905,7 +10898,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_t_1 = __pyx_t_2; __pyx_L14_bool_binop_done:; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":261 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":261 * if not PyDataType_HASFIELDS(descr): * t = descr.type_num * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< @@ -10914,7 +10907,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P */ if (unlikely(__pyx_t_1)) { - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":263 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":263 * if ((descr.byteorder == c'>' and little_endian) or * (descr.byteorder == c'<' and not little_endian)): * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< @@ -10927,7 +10920,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __PYX_ERR(1, 263, __pyx_L1_error) - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":261 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":261 * if not PyDataType_HASFIELDS(descr): * t = descr.type_num * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< @@ -10936,7 +10929,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P */ } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":264 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":264 * (descr.byteorder == c'<' and not little_endian)): * raise ValueError(u"Non-native byte order not supported") * if t == NPY_BYTE: f = "b" # <<<<<<<<<<<<<< @@ -10948,7 +10941,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_v_f = ((char *)"b"); break; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":265 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":265 * raise ValueError(u"Non-native byte order not supported") * if t == NPY_BYTE: f = "b" * elif t == NPY_UBYTE: f = "B" # <<<<<<<<<<<<<< @@ -10959,7 +10952,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_v_f = ((char *)"B"); break; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":266 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":266 * if t == NPY_BYTE: f = "b" * elif t == NPY_UBYTE: f = "B" * elif t == NPY_SHORT: f = "h" # <<<<<<<<<<<<<< @@ -10970,7 +10963,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_v_f = ((char *)"h"); break; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":267 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":267 * elif t == NPY_UBYTE: f = "B" * elif t == NPY_SHORT: f = "h" * elif t == NPY_USHORT: f = "H" # <<<<<<<<<<<<<< @@ -10981,7 +10974,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_v_f = ((char *)"H"); break; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":268 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":268 * elif t == NPY_SHORT: f = "h" * elif t == NPY_USHORT: f = "H" * elif t == NPY_INT: f = "i" # <<<<<<<<<<<<<< @@ -10992,7 +10985,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_v_f = ((char *)"i"); break; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":269 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":269 * elif t == NPY_USHORT: f = "H" * elif t == NPY_INT: f = "i" * elif t == NPY_UINT: f = "I" # <<<<<<<<<<<<<< @@ -11003,7 +10996,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_v_f = ((char *)"I"); break; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":270 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":270 * elif t == NPY_INT: f = "i" * elif t == NPY_UINT: f = "I" * elif t == NPY_LONG: f = "l" # <<<<<<<<<<<<<< @@ -11014,7 +11007,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_v_f = ((char *)"l"); break; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":271 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":271 * elif t == NPY_UINT: f = "I" * elif t == NPY_LONG: f = "l" * elif t == NPY_ULONG: f = "L" # <<<<<<<<<<<<<< @@ -11025,7 +11018,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_v_f = ((char *)"L"); break; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":272 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":272 * elif t == NPY_LONG: f = "l" * elif t == NPY_ULONG: f = "L" * elif t == NPY_LONGLONG: f = "q" # <<<<<<<<<<<<<< @@ -11036,7 +11029,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_v_f = ((char *)"q"); break; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":273 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":273 * elif t == NPY_ULONG: f = "L" * elif t == NPY_LONGLONG: f = "q" * elif t == NPY_ULONGLONG: f = "Q" # <<<<<<<<<<<<<< @@ -11047,7 +11040,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_v_f = ((char *)"Q"); break; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":274 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":274 * elif t == NPY_LONGLONG: f = "q" * elif t == NPY_ULONGLONG: f = "Q" * elif t == NPY_FLOAT: f = "f" # <<<<<<<<<<<<<< @@ -11058,7 +11051,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_v_f = ((char *)"f"); break; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":275 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":275 * elif t == NPY_ULONGLONG: f = "Q" * elif t == NPY_FLOAT: f = "f" * elif t == NPY_DOUBLE: f = "d" # <<<<<<<<<<<<<< @@ -11069,7 +11062,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_v_f = ((char *)"d"); break; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":276 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":276 * elif t == NPY_FLOAT: f = "f" * elif t == NPY_DOUBLE: f = "d" * elif t == NPY_LONGDOUBLE: f = "g" # <<<<<<<<<<<<<< @@ -11080,7 +11073,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_v_f = ((char *)"g"); break; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":277 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":277 * elif t == NPY_DOUBLE: f = "d" * elif t == NPY_LONGDOUBLE: f = "g" * elif t == NPY_CFLOAT: f = "Zf" # <<<<<<<<<<<<<< @@ -11091,7 +11084,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_v_f = ((char *)"Zf"); break; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":278 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":278 * elif t == NPY_LONGDOUBLE: f = "g" * elif t == NPY_CFLOAT: f = "Zf" * elif t == NPY_CDOUBLE: f = "Zd" # <<<<<<<<<<<<<< @@ -11102,7 +11095,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_v_f = ((char *)"Zd"); break; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":279 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":279 * elif t == NPY_CFLOAT: f = "Zf" * elif t == NPY_CDOUBLE: f = "Zd" * elif t == NPY_CLONGDOUBLE: f = "Zg" # <<<<<<<<<<<<<< @@ -11113,7 +11106,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_v_f = ((char *)"Zg"); break; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":280 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":280 * elif t == NPY_CDOUBLE: f = "Zd" * elif t == NPY_CLONGDOUBLE: f = "Zg" * elif t == NPY_OBJECT: f = "O" # <<<<<<<<<<<<<< @@ -11125,7 +11118,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P break; default: - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":282 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":282 * elif t == NPY_OBJECT: f = "O" * else: * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<< @@ -11146,7 +11139,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P break; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":283 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":283 * else: * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) * info.format = f # <<<<<<<<<<<<<< @@ -11155,7 +11148,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P */ __pyx_v_info->format = __pyx_v_f; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":284 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":284 * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) * info.format = f * return # <<<<<<<<<<<<<< @@ -11165,7 +11158,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_r = 0; goto __pyx_L0; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":259 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":259 * info.obj = self * * if not PyDataType_HASFIELDS(descr): # <<<<<<<<<<<<<< @@ -11174,7 +11167,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P */ } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":286 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":286 * return * else: * info.format = PyObject_Malloc(_buffer_format_string_len) # <<<<<<<<<<<<<< @@ -11184,7 +11177,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P /*else*/ { __pyx_v_info->format = ((char *)PyObject_Malloc(0xFF)); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":287 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":287 * else: * info.format = PyObject_Malloc(_buffer_format_string_len) * info.format[0] = c'^' # Native data types, manual alignment # <<<<<<<<<<<<<< @@ -11193,7 +11186,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P */ (__pyx_v_info->format[0]) = '^'; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":288 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":288 * info.format = PyObject_Malloc(_buffer_format_string_len) * info.format[0] = c'^' # Native data types, manual alignment * offset = 0 # <<<<<<<<<<<<<< @@ -11202,7 +11195,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P */ __pyx_v_offset = 0; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":289 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":289 * info.format[0] = c'^' # Native data types, manual alignment * offset = 0 * f = _util_dtypestring(descr, info.format + 1, # <<<<<<<<<<<<<< @@ -11212,7 +11205,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P __pyx_t_8 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 0xFF), (&__pyx_v_offset)); if (unlikely(__pyx_t_8 == ((char *)NULL))) __PYX_ERR(1, 289, __pyx_L1_error) __pyx_v_f = __pyx_t_8; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":292 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":292 * info.format + _buffer_format_string_len, * &offset) * f[0] = c'\0' # Terminate format string # <<<<<<<<<<<<<< @@ -11222,7 +11215,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P (__pyx_v_f[0]) = '\x00'; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":215 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":215 * # experimental exception made for __getbuffer__ and __releasebuffer__ * # -- the details of this may change. * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<< @@ -11254,7 +11247,7 @@ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, P return __pyx_r; } -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":294 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":294 * f[0] = c'\0' # Terminate format string * * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<< @@ -11278,7 +11271,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s int __pyx_t_1; __Pyx_RefNannySetupContext("__releasebuffer__", 0); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":295 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":295 * * def __releasebuffer__(ndarray self, Py_buffer* info): * if PyArray_HASFIELDS(self): # <<<<<<<<<<<<<< @@ -11288,7 +11281,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0); if (__pyx_t_1) { - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":296 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":296 * def __releasebuffer__(ndarray self, Py_buffer* info): * if PyArray_HASFIELDS(self): * PyObject_Free(info.format) # <<<<<<<<<<<<<< @@ -11297,7 +11290,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s */ PyObject_Free(__pyx_v_info->format); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":295 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":295 * * def __releasebuffer__(ndarray self, Py_buffer* info): * if PyArray_HASFIELDS(self): # <<<<<<<<<<<<<< @@ -11306,7 +11299,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s */ } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":297 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":297 * if PyArray_HASFIELDS(self): * PyObject_Free(info.format) * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< @@ -11316,7 +11309,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0); if (__pyx_t_1) { - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":298 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":298 * PyObject_Free(info.format) * if sizeof(npy_intp) != sizeof(Py_ssize_t): * PyObject_Free(info.strides) # <<<<<<<<<<<<<< @@ -11325,7 +11318,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s */ PyObject_Free(__pyx_v_info->strides); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":297 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":297 * if PyArray_HASFIELDS(self): * PyObject_Free(info.format) * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<< @@ -11334,7 +11327,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s */ } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":294 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":294 * f[0] = c'\0' # Terminate format string * * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<< @@ -11346,7 +11339,7 @@ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_s __Pyx_RefNannyFinishContext(); } -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":775 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":775 * ctypedef npy_cdouble complex_t * * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< @@ -11360,7 +11353,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__ PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":776 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":776 * * cdef inline object PyArray_MultiIterNew1(a): * return PyArray_MultiIterNew(1, a) # <<<<<<<<<<<<<< @@ -11374,7 +11367,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__ __pyx_t_1 = 0; goto __pyx_L0; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":775 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":775 * ctypedef npy_cdouble complex_t * * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< @@ -11393,7 +11386,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__ return __pyx_r; } -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":778 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":778 * return PyArray_MultiIterNew(1, a) * * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< @@ -11407,7 +11400,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__ PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":779 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":779 * * cdef inline object PyArray_MultiIterNew2(a, b): * return PyArray_MultiIterNew(2, a, b) # <<<<<<<<<<<<<< @@ -11421,7 +11414,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__ __pyx_t_1 = 0; goto __pyx_L0; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":778 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":778 * return PyArray_MultiIterNew(1, a) * * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< @@ -11440,7 +11433,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__ return __pyx_r; } -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":781 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":781 * return PyArray_MultiIterNew(2, a, b) * * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< @@ -11454,7 +11447,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__ PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":782 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":782 * * cdef inline object PyArray_MultiIterNew3(a, b, c): * return PyArray_MultiIterNew(3, a, b, c) # <<<<<<<<<<<<<< @@ -11468,7 +11461,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__ __pyx_t_1 = 0; goto __pyx_L0; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":781 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":781 * return PyArray_MultiIterNew(2, a, b) * * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< @@ -11487,7 +11480,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__ return __pyx_r; } -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":784 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":784 * return PyArray_MultiIterNew(3, a, b, c) * * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< @@ -11501,7 +11494,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__ PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":785 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":785 * * cdef inline object PyArray_MultiIterNew4(a, b, c, d): * return PyArray_MultiIterNew(4, a, b, c, d) # <<<<<<<<<<<<<< @@ -11515,7 +11508,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__ __pyx_t_1 = 0; goto __pyx_L0; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":784 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":784 * return PyArray_MultiIterNew(3, a, b, c) * * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< @@ -11534,7 +11527,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__ return __pyx_r; } -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":787 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":787 * return PyArray_MultiIterNew(4, a, b, c, d) * * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< @@ -11548,7 +11541,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__ PyObject *__pyx_t_1 = NULL; __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":788 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":788 * * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): * return PyArray_MultiIterNew(5, a, b, c, d, e) # <<<<<<<<<<<<<< @@ -11562,7 +11555,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__ __pyx_t_1 = 0; goto __pyx_L0; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":787 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":787 * return PyArray_MultiIterNew(4, a, b, c, d) * * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< @@ -11581,7 +11574,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__ return __pyx_r; } -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":790 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":790 * return PyArray_MultiIterNew(5, a, b, c, d, e) * * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< @@ -11595,7 +11588,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__ int __pyx_t_1; __Pyx_RefNannySetupContext("PyDataType_SHAPE", 0); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":791 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":791 * * cdef inline tuple PyDataType_SHAPE(dtype d): * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< @@ -11605,7 +11598,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__ __pyx_t_1 = (PyDataType_HASSUBARRAY(__pyx_v_d) != 0); if (__pyx_t_1) { - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":792 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":792 * cdef inline tuple PyDataType_SHAPE(dtype d): * if PyDataType_HASSUBARRAY(d): * return d.subarray.shape # <<<<<<<<<<<<<< @@ -11617,7 +11610,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__ __pyx_r = ((PyObject*)__pyx_v_d->subarray->shape); goto __pyx_L0; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":791 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":791 * * cdef inline tuple PyDataType_SHAPE(dtype d): * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< @@ -11626,7 +11619,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__ */ } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":794 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":794 * return d.subarray.shape * else: * return () # <<<<<<<<<<<<<< @@ -11640,7 +11633,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__ goto __pyx_L0; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":790 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":790 * return PyArray_MultiIterNew(5, a, b, c, d, e) * * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< @@ -11655,7 +11648,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__ return __pyx_r; } -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":796 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":796 * return () * * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<< @@ -11684,7 +11677,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx char *__pyx_t_9; __Pyx_RefNannySetupContext("_util_dtypestring", 0); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":801 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":801 * * cdef dtype child * cdef int endian_detector = 1 # <<<<<<<<<<<<<< @@ -11693,7 +11686,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx */ __pyx_v_endian_detector = 1; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":802 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":802 * cdef dtype child * cdef int endian_detector = 1 * cdef bint little_endian = ((&endian_detector)[0] != 0) # <<<<<<<<<<<<<< @@ -11702,7 +11695,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx */ __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":805 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":805 * cdef tuple fields * * for childname in descr.names: # <<<<<<<<<<<<<< @@ -11725,7 +11718,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3); __pyx_t_3 = 0; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":806 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":806 * * for childname in descr.names: * fields = descr.fields[childname] # <<<<<<<<<<<<<< @@ -11742,7 +11735,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3)); __pyx_t_3 = 0; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":807 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":807 * for childname in descr.names: * fields = descr.fields[childname] * child, new_offset = fields # <<<<<<<<<<<<<< @@ -11777,7 +11770,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4); __pyx_t_4 = 0; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":809 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":809 * child, new_offset = fields * * if (end - f) - (new_offset - offset[0]) < 15: # <<<<<<<<<<<<<< @@ -11794,7 +11787,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0); if (unlikely(__pyx_t_6)) { - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":810 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":810 * * if (end - f) - (new_offset - offset[0]) < 15: * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<< @@ -11807,7 +11800,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __PYX_ERR(1, 810, __pyx_L1_error) - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":809 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":809 * child, new_offset = fields * * if (end - f) - (new_offset - offset[0]) < 15: # <<<<<<<<<<<<<< @@ -11816,7 +11809,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx */ } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":812 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":812 * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") * * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< @@ -11836,7 +11829,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx } __pyx_L8_next_or:; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":813 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":813 * * if ((child.byteorder == c'>' and little_endian) or * (child.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<< @@ -11853,7 +11846,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx __pyx_t_6 = __pyx_t_7; __pyx_L7_bool_binop_done:; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":812 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":812 * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") * * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< @@ -11862,7 +11855,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx */ if (unlikely(__pyx_t_6)) { - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":814 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":814 * if ((child.byteorder == c'>' and little_endian) or * (child.byteorder == c'<' and not little_endian)): * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< @@ -11875,7 +11868,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __PYX_ERR(1, 814, __pyx_L1_error) - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":812 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":812 * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") * * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<< @@ -11884,7 +11877,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx */ } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":824 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":824 * * # Output padding bytes * while offset[0] < new_offset: # <<<<<<<<<<<<<< @@ -11900,7 +11893,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; if (!__pyx_t_6) break; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":825 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":825 * # Output padding bytes * while offset[0] < new_offset: * f[0] = 120 # "x"; pad byte # <<<<<<<<<<<<<< @@ -11909,7 +11902,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx */ (__pyx_v_f[0]) = 0x78; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":826 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":826 * while offset[0] < new_offset: * f[0] = 120 # "x"; pad byte * f += 1 # <<<<<<<<<<<<<< @@ -11918,7 +11911,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx */ __pyx_v_f = (__pyx_v_f + 1); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":827 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":827 * f[0] = 120 # "x"; pad byte * f += 1 * offset[0] += 1 # <<<<<<<<<<<<<< @@ -11929,7 +11922,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1); } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":829 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":829 * offset[0] += 1 * * offset[0] += child.itemsize # <<<<<<<<<<<<<< @@ -11939,7 +11932,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx __pyx_t_8 = 0; (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":831 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":831 * offset[0] += child.itemsize * * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<< @@ -11949,7 +11942,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0); if (__pyx_t_6) { - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":832 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":832 * * if not PyDataType_HASFIELDS(child): * t = child.type_num # <<<<<<<<<<<<<< @@ -11961,7 +11954,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4); __pyx_t_4 = 0; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":833 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":833 * if not PyDataType_HASFIELDS(child): * t = child.type_num * if end - f < 5: # <<<<<<<<<<<<<< @@ -11971,7 +11964,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0); if (unlikely(__pyx_t_6)) { - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":834 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":834 * t = child.type_num * if end - f < 5: * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<< @@ -11984,7 +11977,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __PYX_ERR(1, 834, __pyx_L1_error) - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":833 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":833 * if not PyDataType_HASFIELDS(child): * t = child.type_num * if end - f < 5: # <<<<<<<<<<<<<< @@ -11993,7 +11986,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx */ } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":837 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":837 * * # Until ticket #99 is fixed, use integers to avoid warnings * if t == NPY_BYTE: f[0] = 98 #"b" # <<<<<<<<<<<<<< @@ -12011,7 +12004,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx goto __pyx_L15; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":838 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":838 * # Until ticket #99 is fixed, use integers to avoid warnings * if t == NPY_BYTE: f[0] = 98 #"b" * elif t == NPY_UBYTE: f[0] = 66 #"B" # <<<<<<<<<<<<<< @@ -12029,7 +12022,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx goto __pyx_L15; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":839 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":839 * if t == NPY_BYTE: f[0] = 98 #"b" * elif t == NPY_UBYTE: f[0] = 66 #"B" * elif t == NPY_SHORT: f[0] = 104 #"h" # <<<<<<<<<<<<<< @@ -12047,7 +12040,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx goto __pyx_L15; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":840 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":840 * elif t == NPY_UBYTE: f[0] = 66 #"B" * elif t == NPY_SHORT: f[0] = 104 #"h" * elif t == NPY_USHORT: f[0] = 72 #"H" # <<<<<<<<<<<<<< @@ -12065,7 +12058,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx goto __pyx_L15; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":841 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":841 * elif t == NPY_SHORT: f[0] = 104 #"h" * elif t == NPY_USHORT: f[0] = 72 #"H" * elif t == NPY_INT: f[0] = 105 #"i" # <<<<<<<<<<<<<< @@ -12083,7 +12076,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx goto __pyx_L15; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":842 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":842 * elif t == NPY_USHORT: f[0] = 72 #"H" * elif t == NPY_INT: f[0] = 105 #"i" * elif t == NPY_UINT: f[0] = 73 #"I" # <<<<<<<<<<<<<< @@ -12101,7 +12094,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx goto __pyx_L15; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":843 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":843 * elif t == NPY_INT: f[0] = 105 #"i" * elif t == NPY_UINT: f[0] = 73 #"I" * elif t == NPY_LONG: f[0] = 108 #"l" # <<<<<<<<<<<<<< @@ -12119,7 +12112,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx goto __pyx_L15; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":844 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":844 * elif t == NPY_UINT: f[0] = 73 #"I" * elif t == NPY_LONG: f[0] = 108 #"l" * elif t == NPY_ULONG: f[0] = 76 #"L" # <<<<<<<<<<<<<< @@ -12137,7 +12130,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx goto __pyx_L15; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":845 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":845 * elif t == NPY_LONG: f[0] = 108 #"l" * elif t == NPY_ULONG: f[0] = 76 #"L" * elif t == NPY_LONGLONG: f[0] = 113 #"q" # <<<<<<<<<<<<<< @@ -12155,7 +12148,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx goto __pyx_L15; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":846 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":846 * elif t == NPY_ULONG: f[0] = 76 #"L" * elif t == NPY_LONGLONG: f[0] = 113 #"q" * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" # <<<<<<<<<<<<<< @@ -12173,7 +12166,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx goto __pyx_L15; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":847 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":847 * elif t == NPY_LONGLONG: f[0] = 113 #"q" * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" * elif t == NPY_FLOAT: f[0] = 102 #"f" # <<<<<<<<<<<<<< @@ -12191,7 +12184,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx goto __pyx_L15; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":848 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":848 * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" * elif t == NPY_FLOAT: f[0] = 102 #"f" * elif t == NPY_DOUBLE: f[0] = 100 #"d" # <<<<<<<<<<<<<< @@ -12209,7 +12202,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx goto __pyx_L15; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":849 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":849 * elif t == NPY_FLOAT: f[0] = 102 #"f" * elif t == NPY_DOUBLE: f[0] = 100 #"d" * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" # <<<<<<<<<<<<<< @@ -12227,7 +12220,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx goto __pyx_L15; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":850 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":850 * elif t == NPY_DOUBLE: f[0] = 100 #"d" * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf # <<<<<<<<<<<<<< @@ -12247,7 +12240,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx goto __pyx_L15; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":851 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":851 * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd # <<<<<<<<<<<<<< @@ -12267,7 +12260,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx goto __pyx_L15; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":852 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":852 * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg # <<<<<<<<<<<<<< @@ -12287,7 +12280,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx goto __pyx_L15; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":853 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":853 * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg * elif t == NPY_OBJECT: f[0] = 79 #"O" # <<<<<<<<<<<<<< @@ -12305,7 +12298,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx goto __pyx_L15; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":855 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":855 * elif t == NPY_OBJECT: f[0] = 79 #"O" * else: * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<< @@ -12324,7 +12317,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx } __pyx_L15:; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":856 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":856 * else: * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) * f += 1 # <<<<<<<<<<<<<< @@ -12333,7 +12326,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx */ __pyx_v_f = (__pyx_v_f + 1); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":831 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":831 * offset[0] += child.itemsize * * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<< @@ -12343,7 +12336,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx goto __pyx_L13; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":860 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":860 * # Cython ignores struct boundary information ("T{...}"), * # so don't output it * f = _util_dtypestring(child, f, end, offset) # <<<<<<<<<<<<<< @@ -12356,7 +12349,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx } __pyx_L13:; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":805 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":805 * cdef tuple fields * * for childname in descr.names: # <<<<<<<<<<<<<< @@ -12366,7 +12359,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":861 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":861 * # so don't output it * f = _util_dtypestring(child, f, end, offset) * return f # <<<<<<<<<<<<<< @@ -12376,7 +12369,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx __pyx_r = __pyx_v_f; goto __pyx_L0; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":796 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":796 * return () * * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<< @@ -12401,7 +12394,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx return __pyx_r; } -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":977 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":977 * * * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< @@ -12416,7 +12409,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a int __pyx_t_2; __Pyx_RefNannySetupContext("set_array_base", 0); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":979 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":979 * cdef inline void set_array_base(ndarray arr, object base): * cdef PyObject* baseptr * if base is None: # <<<<<<<<<<<<<< @@ -12427,7 +12420,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a __pyx_t_2 = (__pyx_t_1 != 0); if (__pyx_t_2) { - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":980 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":980 * cdef PyObject* baseptr * if base is None: * baseptr = NULL # <<<<<<<<<<<<<< @@ -12436,7 +12429,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a */ __pyx_v_baseptr = NULL; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":979 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":979 * cdef inline void set_array_base(ndarray arr, object base): * cdef PyObject* baseptr * if base is None: # <<<<<<<<<<<<<< @@ -12446,7 +12439,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a goto __pyx_L3; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":982 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":982 * baseptr = NULL * else: * Py_INCREF(base) # important to do this before decref below! # <<<<<<<<<<<<<< @@ -12456,7 +12449,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a /*else*/ { Py_INCREF(__pyx_v_base); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":983 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":983 * else: * Py_INCREF(base) # important to do this before decref below! * baseptr = base # <<<<<<<<<<<<<< @@ -12467,7 +12460,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a } __pyx_L3:; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":984 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":984 * Py_INCREF(base) # important to do this before decref below! * baseptr = base * Py_XDECREF(arr.base) # <<<<<<<<<<<<<< @@ -12476,7 +12469,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a */ Py_XDECREF(__pyx_v_arr->base); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":985 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":985 * baseptr = base * Py_XDECREF(arr.base) * arr.base = baseptr # <<<<<<<<<<<<<< @@ -12485,7 +12478,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a */ __pyx_v_arr->base = __pyx_v_baseptr; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":977 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":977 * * * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<< @@ -12497,7 +12490,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a __Pyx_RefNannyFinishContext(); } -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":987 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":987 * arr.base = baseptr * * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< @@ -12511,7 +12504,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py int __pyx_t_1; __Pyx_RefNannySetupContext("get_array_base", 0); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":988 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":988 * * cdef inline object get_array_base(ndarray arr): * if arr.base is NULL: # <<<<<<<<<<<<<< @@ -12521,7 +12514,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0); if (__pyx_t_1) { - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":989 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":989 * cdef inline object get_array_base(ndarray arr): * if arr.base is NULL: * return None # <<<<<<<<<<<<<< @@ -12532,7 +12525,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":988 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":988 * * cdef inline object get_array_base(ndarray arr): * if arr.base is NULL: # <<<<<<<<<<<<<< @@ -12541,7 +12534,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py */ } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":991 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":991 * return None * else: * return arr.base # <<<<<<<<<<<<<< @@ -12555,7 +12548,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py goto __pyx_L0; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":987 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":987 * arr.base = baseptr * * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< @@ -12570,7 +12563,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py return __pyx_r; } -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":996 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":996 * # Versions of the import_* functions which are more suitable for * # Cython code. * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< @@ -12591,7 +12584,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { PyObject *__pyx_t_8 = NULL; __Pyx_RefNannySetupContext("import_array", 0); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":997 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":997 * # Cython code. * cdef inline int import_array() except -1: * try: # <<<<<<<<<<<<<< @@ -12607,7 +12600,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { __Pyx_XGOTREF(__pyx_t_3); /*try:*/ { - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":998 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":998 * cdef inline int import_array() except -1: * try: * _import_array() # <<<<<<<<<<<<<< @@ -12616,7 +12609,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { */ __pyx_t_4 = _import_array(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 998, __pyx_L3_error) - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":997 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":997 * # Cython code. * cdef inline int import_array() except -1: * try: # <<<<<<<<<<<<<< @@ -12630,7 +12623,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { goto __pyx_L8_try_end; __pyx_L3_error:; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":999 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":999 * try: * _import_array() * except Exception: # <<<<<<<<<<<<<< @@ -12645,7 +12638,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { __Pyx_GOTREF(__pyx_t_6); __Pyx_GOTREF(__pyx_t_7); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":1000 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":1000 * _import_array() * except Exception: * raise ImportError("numpy.core.multiarray failed to import") # <<<<<<<<<<<<<< @@ -12661,7 +12654,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { goto __pyx_L5_except_error; __pyx_L5_except_error:; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":997 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":997 * # Cython code. * cdef inline int import_array() except -1: * try: # <<<<<<<<<<<<<< @@ -12676,7 +12669,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { __pyx_L8_try_end:; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":996 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":996 * # Versions of the import_* functions which are more suitable for * # Cython code. * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< @@ -12699,7 +12692,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { return __pyx_r; } -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":1002 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":1002 * raise ImportError("numpy.core.multiarray failed to import") * * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< @@ -12720,7 +12713,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { PyObject *__pyx_t_8 = NULL; __Pyx_RefNannySetupContext("import_umath", 0); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":1003 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":1003 * * cdef inline int import_umath() except -1: * try: # <<<<<<<<<<<<<< @@ -12736,7 +12729,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { __Pyx_XGOTREF(__pyx_t_3); /*try:*/ { - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":1004 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":1004 * cdef inline int import_umath() except -1: * try: * _import_umath() # <<<<<<<<<<<<<< @@ -12745,7 +12738,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { */ __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 1004, __pyx_L3_error) - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":1003 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":1003 * * cdef inline int import_umath() except -1: * try: # <<<<<<<<<<<<<< @@ -12759,7 +12752,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { goto __pyx_L8_try_end; __pyx_L3_error:; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":1005 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":1005 * try: * _import_umath() * except Exception: # <<<<<<<<<<<<<< @@ -12774,7 +12767,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { __Pyx_GOTREF(__pyx_t_6); __Pyx_GOTREF(__pyx_t_7); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":1006 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":1006 * _import_umath() * except Exception: * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< @@ -12790,7 +12783,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { goto __pyx_L5_except_error; __pyx_L5_except_error:; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":1003 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":1003 * * cdef inline int import_umath() except -1: * try: # <<<<<<<<<<<<<< @@ -12805,7 +12798,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { __pyx_L8_try_end:; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":1002 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":1002 * raise ImportError("numpy.core.multiarray failed to import") * * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< @@ -12828,7 +12821,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { return __pyx_r; } -/* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":1008 +/* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":1008 * raise ImportError("numpy.core.umath failed to import") * * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< @@ -12849,7 +12842,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { PyObject *__pyx_t_8 = NULL; __Pyx_RefNannySetupContext("import_ufunc", 0); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":1009 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":1009 * * cdef inline int import_ufunc() except -1: * try: # <<<<<<<<<<<<<< @@ -12865,7 +12858,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { __Pyx_XGOTREF(__pyx_t_3); /*try:*/ { - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":1010 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":1010 * cdef inline int import_ufunc() except -1: * try: * _import_umath() # <<<<<<<<<<<<<< @@ -12874,7 +12867,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { */ __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 1010, __pyx_L3_error) - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":1009 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":1009 * * cdef inline int import_ufunc() except -1: * try: # <<<<<<<<<<<<<< @@ -12888,7 +12881,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { goto __pyx_L8_try_end; __pyx_L3_error:; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":1011 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":1011 * try: * _import_umath() * except Exception: # <<<<<<<<<<<<<< @@ -12902,7 +12895,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { __Pyx_GOTREF(__pyx_t_6); __Pyx_GOTREF(__pyx_t_7); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":1012 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":1012 * _import_umath() * except Exception: * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< @@ -12916,7 +12909,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { goto __pyx_L5_except_error; __pyx_L5_except_error:; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":1009 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":1009 * * cdef inline int import_ufunc() except -1: * try: # <<<<<<<<<<<<<< @@ -12931,7 +12924,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { __pyx_L8_try_end:; } - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":1008 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":1008 * raise ImportError("numpy.core.umath failed to import") * * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< @@ -13048,7 +13041,7 @@ static int __Pyx_InitCachedConstants(void) { __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":229 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":229 * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<< @@ -13059,7 +13052,7 @@ static int __Pyx_InitCachedConstants(void) { __Pyx_GOTREF(__pyx_tuple_); __Pyx_GIVEREF(__pyx_tuple_); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":233 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":233 * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<< @@ -13070,7 +13063,7 @@ static int __Pyx_InitCachedConstants(void) { __Pyx_GOTREF(__pyx_tuple__2); __Pyx_GIVEREF(__pyx_tuple__2); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":263 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":263 * if ((descr.byteorder == c'>' and little_endian) or * (descr.byteorder == c'<' and not little_endian)): * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< @@ -13081,7 +13074,7 @@ static int __Pyx_InitCachedConstants(void) { __Pyx_GOTREF(__pyx_tuple__3); __Pyx_GIVEREF(__pyx_tuple__3); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":810 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":810 * * if (end - f) - (new_offset - offset[0]) < 15: * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<< @@ -13092,7 +13085,7 @@ static int __Pyx_InitCachedConstants(void) { __Pyx_GOTREF(__pyx_tuple__4); __Pyx_GIVEREF(__pyx_tuple__4); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":814 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":814 * if ((child.byteorder == c'>' and little_endian) or * (child.byteorder == c'<' and not little_endian)): * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<< @@ -13103,7 +13096,7 @@ static int __Pyx_InitCachedConstants(void) { __Pyx_GOTREF(__pyx_tuple__5); __Pyx_GIVEREF(__pyx_tuple__5); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":834 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":834 * t = child.type_num * if end - f < 5: * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<< @@ -13114,7 +13107,7 @@ static int __Pyx_InitCachedConstants(void) { __Pyx_GOTREF(__pyx_tuple__6); __Pyx_GIVEREF(__pyx_tuple__6); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":1000 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":1000 * _import_array() * except Exception: * raise ImportError("numpy.core.multiarray failed to import") # <<<<<<<<<<<<<< @@ -13125,7 +13118,7 @@ static int __Pyx_InitCachedConstants(void) { __Pyx_GOTREF(__pyx_tuple__7); __Pyx_GIVEREF(__pyx_tuple__7); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":1006 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":1006 * _import_umath() * except Exception: * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< @@ -13136,7 +13129,7 @@ static int __Pyx_InitCachedConstants(void) { __Pyx_GOTREF(__pyx_tuple__8); __Pyx_GIVEREF(__pyx_tuple__8); - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":1012 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":1012 * _import_umath() * except Exception: * raise ImportError("numpy.core.umath failed to import") # <<<<<<<<<<<<<< @@ -13476,7 +13469,7 @@ if (!__Pyx_RefNanny) { if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) __PYX_ERR(0, 1, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - /* "../../../../usr/local/lib/python3.5/dist-packages/Cython/Includes/numpy/__init__.pxd":1008 + /* "../../../../usr/lib/python3/dist-packages/Cython/Includes/numpy/__init__.pxd":1008 * raise ImportError("numpy.core.umath failed to import") * * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< @@ -14738,6 +14731,21 @@ static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject } #endif +/* None */ + static CYTHON_INLINE long __Pyx_div_long(long a, long b) { + long q = a / b; + long r = a - q*b; + q -= ((r != 0) & ((r ^ b) < 0)); + return q; +} + +/* None */ + static CYTHON_INLINE long __Pyx_mod_long(long a, long b) { + long r = a % b; + r += ((r != 0) & ((r ^ b) < 0)) * b; + return r; +} + /* SetItemInt */ static int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) { int r; @@ -14985,7 +14993,7 @@ static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) { /* SaveResetException */ #if CYTHON_FAST_THREAD_STATE static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { - #if PY_VERSION_HEX >= 0x030700A2 + #if PY_VERSION_HEX >= 0x030700A3 *type = tstate->exc_state.exc_type; *value = tstate->exc_state.exc_value; *tb = tstate->exc_state.exc_traceback; @@ -15000,7 +15008,7 @@ static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject * } static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { PyObject *tmp_type, *tmp_value, *tmp_tb; - #if PY_VERSION_HEX >= 0x030700A2 + #if PY_VERSION_HEX >= 0x030700A3 tmp_type = tstate->exc_state.exc_type; tmp_value = tstate->exc_state.exc_value; tmp_tb = tstate->exc_state.exc_traceback; @@ -15084,7 +15092,7 @@ static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) *value = local_value; *tb = local_tb; #if CYTHON_FAST_THREAD_STATE - #if PY_VERSION_HEX >= 0x030700A2 + #if PY_VERSION_HEX >= 0x030700A3 tmp_type = tstate->exc_state.exc_type; tmp_value = tstate->exc_state.exc_value; tmp_tb = tstate->exc_state.exc_traceback; @@ -17068,14 +17076,42 @@ static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, return res; } #endif +static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + assert(PyExceptionClass_Check(exc_type)); + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; i Date: Mon, 24 Sep 2018 23:44:29 +0200 Subject: [PATCH 08/61] change dataRead input from posByteEnd to nBytes for simplifications --- dataRead.c | 1574 +++++++++++++++++---------------------- dataRead.pyx | 60 +- mdfreader/mdf3reader.py | 2 +- mdfreader/mdf4reader.py | 2 +- 4 files changed, 729 insertions(+), 909 deletions(-) diff --git a/dataRead.c b/dataRead.c index 5d85304..a4096a0 100644 --- a/dataRead.c +++ b/dataRead.c @@ -1,5 +1,18 @@ /* Generated by Cython 0.28.4 */ +/* BEGIN: Cython Metadata +{ + "distutils": { + "depends": [], + "name": "dataRead", + "sources": [ + "dataRead.pyx" + ] + }, + "module_name": "dataRead" +} +END: Cython Metadata */ + #define PY_SSIZE_T_CLEAN #include "Python.h" #ifndef Py_PYTHON_H @@ -1304,12 +1317,6 @@ static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject #define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) #endif -/* None.proto */ -static CYTHON_INLINE long __Pyx_div_long(long, long); - -/* None.proto */ -static CYTHON_INLINE long __Pyx_mod_long(long, long); - /* SetItemInt.proto */ #define __Pyx_SetItemInt(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ @@ -1626,10 +1633,10 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUChar(char const *, PyO static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadChar(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char); /*proto*/ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUShort(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char, unsigned char); /*proto*/ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadShort(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char, unsigned char); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char, unsigned char); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char, unsigned char); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char, unsigned char); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char, unsigned char); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char, unsigned long, unsigned char); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char, unsigned long, unsigned char); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char, unsigned long, unsigned char); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char, unsigned long, unsigned char); /*proto*/ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadByte(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned long, unsigned char); /*proto*/ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned long, unsigned char, unsigned char); /*proto*/ static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t = { "float32_t", NULL, sizeof(__pyx_t_5numpy_float32_t), { 0 }, 0, 'R', 0, 0 }; @@ -1667,6 +1674,7 @@ static const char __pyx_k_numpy[] = "numpy"; static const char __pyx_k_range[] = "range"; static const char __pyx_k_import[] = "__import__"; static const char __pyx_k_little[] = "little"; +static const char __pyx_k_nBytes[] = "nBytes"; static const char __pyx_k_bitCount[] = "bitCount"; static const char __pyx_k_byteswap[] = "byteswap"; static const char __pyx_k_dataRead[] = "dataRead"; @@ -1675,7 +1683,6 @@ static const char __pyx_k_byteorder[] = "byteorder"; static const char __pyx_k_ValueError[] = "ValueError"; static const char __pyx_k_fromstring[] = "fromstring"; static const char __pyx_k_posByteBeg[] = "posByteBeg"; -static const char __pyx_k_posByteEnd[] = "posByteEnd"; static const char __pyx_k_ImportError[] = "ImportError"; static const char __pyx_k_RecordFormat[] = "RecordFormat"; static const char __pyx_k_RuntimeError[] = "RuntimeError"; @@ -1717,6 +1724,7 @@ static PyObject *__pyx_n_s_fromstring; static PyObject *__pyx_n_s_import; static PyObject *__pyx_n_s_little; static PyObject *__pyx_n_s_main; +static PyObject *__pyx_n_s_nBytes; static PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous; static PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou; static PyObject *__pyx_n_s_np; @@ -1725,7 +1733,6 @@ static PyObject *__pyx_n_s_numpy; static PyObject *__pyx_kp_s_numpy_core_multiarray_failed_to; static PyObject *__pyx_kp_s_numpy_core_umath_failed_to_impor; static PyObject *__pyx_n_s_posByteBeg; -static PyObject *__pyx_n_s_posByteEnd; static PyObject *__pyx_n_s_range; static PyObject *__pyx_n_s_record_byte_size; static PyObject *__pyx_n_s_signalDataType; @@ -1733,7 +1740,7 @@ static PyObject *__pyx_n_s_sys; static PyObject *__pyx_n_s_test; static PyObject *__pyx_n_s_tmp; static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd; -static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_tmp, unsigned short __pyx_v_bitCount, unsigned short __pyx_v_signalDataType, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned char __pyx_v_bitOffset, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_posByteEnd, PyObject *__pyx_v_array); /* proto */ +static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_tmp, unsigned short __pyx_v_bitCount, unsigned short __pyx_v_signalDataType, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned char __pyx_v_bitOffset, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_nBytes, PyObject *__pyx_v_array); /* proto */ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */ static PyObject *__pyx_tuple_; @@ -1759,7 +1766,7 @@ static PyObject *__pyx_codeobj__11; /* Python wrapper */ static PyObject *__pyx_pw_8dataRead_1dataRead(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_8dataRead_dataRead[] = "dataRead function to read in cython a channel from a byte stream\n\n Parameters\n ------------\n tmp : bytes\n byte stream\n bitCount : unsigned short\n number of bit taken by the channel in the record\n signalDataType : unsigned short\n int to describe data type\n RecordFormat : string\n basic numpy dtype description of data type, used to create\n\t returned numpy ndarray\n numberOfRecords : unsigned long long\n number of records in byte stream\n record_byte_size : unsigned long\n number of bytes taken by one record repeated in byte stream\n bitOffset : unsigned char\n bit offset of data in C aligned bytes\n posByteBeg : unsigned long\n beginning byte position of channel in record\n posByteEnd : unsigned long\n ending byte position of channel in record\n array : boolean\n reads an array, not a vector\n\n Return\n -------\n ndarray of type RecordFormat with numberOfRecords records.\n Byte order is swapped if necessary to match machine byte order before bits offset and masking\n "; +static char __pyx_doc_8dataRead_dataRead[] = "dataRead function to read in cython a channel from a byte stream\n\n Parameters\n ------------\n tmp : bytes\n byte stream\n bitCount : unsigned short\n number of bit taken by the channel in the record\n signalDataType : unsigned short\n int to describe data type\n RecordFormat : string\n basic numpy dtype description of data type, used to create\n\t returned numpy ndarray\n numberOfRecords : unsigned long long\n number of records in byte stream\n record_byte_size : unsigned long\n number of bytes taken by one record repeated in byte stream\n bitOffset : unsigned char\n bit offset of data in C aligned bytes\n posByteBeg : unsigned long\n beginning byte position of channel in record\n nBytes : unsigned long\n bytes length of channel in record\n array : boolean\n reads an array, not a vector\n\n Return\n -------\n ndarray of type RecordFormat with numberOfRecords records.\n Byte order is swapped if necessary to match machine byte order before bits offset and masking\n "; static PyMethodDef __pyx_mdef_8dataRead_1dataRead = {"dataRead", (PyCFunction)__pyx_pw_8dataRead_1dataRead, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8dataRead_dataRead}; static PyObject *__pyx_pw_8dataRead_1dataRead(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_tmp = 0; @@ -1770,13 +1777,13 @@ static PyObject *__pyx_pw_8dataRead_1dataRead(PyObject *__pyx_self, PyObject *__ unsigned long __pyx_v_record_byte_size; unsigned char __pyx_v_bitOffset; unsigned long __pyx_v_posByteBeg; - unsigned long __pyx_v_posByteEnd; + unsigned long __pyx_v_nBytes; PyObject *__pyx_v_array = 0; PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations __Pyx_RefNannySetupContext("dataRead (wrapper)", 0); { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_tmp,&__pyx_n_s_bitCount,&__pyx_n_s_signalDataType,&__pyx_n_s_RecordFormat,&__pyx_n_s_numberOfRecords,&__pyx_n_s_record_byte_size,&__pyx_n_s_bitOffset,&__pyx_n_s_posByteBeg,&__pyx_n_s_posByteEnd,&__pyx_n_s_array,0}; + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_tmp,&__pyx_n_s_bitCount,&__pyx_n_s_signalDataType,&__pyx_n_s_RecordFormat,&__pyx_n_s_numberOfRecords,&__pyx_n_s_record_byte_size,&__pyx_n_s_bitOffset,&__pyx_n_s_posByteBeg,&__pyx_n_s_nBytes,&__pyx_n_s_array,0}; PyObject* values[10] = {0,0,0,0,0,0,0,0,0,0}; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; @@ -1854,7 +1861,7 @@ static PyObject *__pyx_pw_8dataRead_1dataRead(PyObject *__pyx_self, PyObject *__ } CYTHON_FALLTHROUGH; case 8: - if (likely((values[8] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_posByteEnd)) != 0)) kw_args--; + if (likely((values[8] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_nBytes)) != 0)) kw_args--; else { __Pyx_RaiseArgtupleInvalid("dataRead", 1, 10, 10, 8); __PYX_ERR(0, 11, __pyx_L3_error) } @@ -1890,7 +1897,7 @@ static PyObject *__pyx_pw_8dataRead_1dataRead(PyObject *__pyx_self, PyObject *__ __pyx_v_record_byte_size = __Pyx_PyInt_As_unsigned_long(values[5]); if (unlikely((__pyx_v_record_byte_size == (unsigned long)-1) && PyErr_Occurred())) __PYX_ERR(0, 13, __pyx_L3_error) __pyx_v_bitOffset = __Pyx_PyInt_As_unsigned_char(values[6]); if (unlikely((__pyx_v_bitOffset == (unsigned char)-1) && PyErr_Occurred())) __PYX_ERR(0, 13, __pyx_L3_error) __pyx_v_posByteBeg = __Pyx_PyInt_As_unsigned_long(values[7]); if (unlikely((__pyx_v_posByteBeg == (unsigned long)-1) && PyErr_Occurred())) __PYX_ERR(0, 14, __pyx_L3_error) - __pyx_v_posByteEnd = __Pyx_PyInt_As_unsigned_long(values[8]); if (unlikely((__pyx_v_posByteEnd == (unsigned long)-1) && PyErr_Occurred())) __PYX_ERR(0, 14, __pyx_L3_error) + __pyx_v_nBytes = __Pyx_PyInt_As_unsigned_long(values[8]); if (unlikely((__pyx_v_nBytes == (unsigned long)-1) && PyErr_Occurred())) __PYX_ERR(0, 14, __pyx_L3_error) __pyx_v_array = values[9]; } goto __pyx_L4_argument_unpacking_done; @@ -1903,7 +1910,7 @@ static PyObject *__pyx_pw_8dataRead_1dataRead(PyObject *__pyx_self, PyObject *__ __pyx_L4_argument_unpacking_done:; if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_tmp), (&PyBytes_Type), 1, "tmp", 1))) __PYX_ERR(0, 11, __pyx_L1_error) if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_RecordFormat), (&PyString_Type), 1, "RecordFormat", 1))) __PYX_ERR(0, 12, __pyx_L1_error) - __pyx_r = __pyx_pf_8dataRead_dataRead(__pyx_self, __pyx_v_tmp, __pyx_v_bitCount, __pyx_v_signalDataType, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_bitOffset, __pyx_v_posByteBeg, __pyx_v_posByteEnd, __pyx_v_array); + __pyx_r = __pyx_pf_8dataRead_dataRead(__pyx_self, __pyx_v_tmp, __pyx_v_bitCount, __pyx_v_signalDataType, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_bitOffset, __pyx_v_posByteBeg, __pyx_v_nBytes, __pyx_v_array); /* function exit code */ goto __pyx_L0; @@ -1914,7 +1921,7 @@ static PyObject *__pyx_pw_8dataRead_1dataRead(PyObject *__pyx_self, PyObject *__ return __pyx_r; } -static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_tmp, unsigned short __pyx_v_bitCount, unsigned short __pyx_v_signalDataType, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned char __pyx_v_bitOffset, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_posByteEnd, PyObject *__pyx_v_array) { +static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_tmp, unsigned short __pyx_v_bitCount, unsigned short __pyx_v_signalDataType, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned char __pyx_v_bitOffset, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_nBytes, PyObject *__pyx_v_array) { char *__pyx_v_bita; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations @@ -1951,7 +1958,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * if not array: * if 'V' in RecordFormat or 'S' in RecordFormat or RecordFormat is None: # <<<<<<<<<<<<<< * return dataReadByte(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset) + * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) */ __pyx_t_2 = (__Pyx_PySequence_ContainsTF(__pyx_n_s_V, __pyx_v_RecordFormat, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 48, __pyx_L1_error) __pyx_t_4 = (__pyx_t_2 != 0); @@ -1977,7 +1984,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * if not array: * if 'V' in RecordFormat or 'S' in RecordFormat or RecordFormat is None: * return dataReadByte(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset) + * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) * elif signalDataType in (4, 5) and bitCount == 32: # float */ __Pyx_XDECREF(__pyx_r); @@ -1985,11 +1992,11 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":50 * if 'V' in RecordFormat or 'S' in RecordFormat or RecordFormat is None: * return dataReadByte(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset) # <<<<<<<<<<<<<< + * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) # <<<<<<<<<<<<<< * elif signalDataType in (4, 5) and bitCount == 32: # float * if (byteorder == 'little' and signalDataType == 4) or \ */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadByte(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_posByteEnd, __pyx_v_bitCount, __pyx_v_bitOffset); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 49, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_dataReadByte(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_nBytes, __pyx_v_bitCount, __pyx_v_bitOffset); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 49, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; @@ -2000,13 +2007,13 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * if not array: * if 'V' in RecordFormat or 'S' in RecordFormat or RecordFormat is None: # <<<<<<<<<<<<<< * return dataReadByte(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset) + * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) */ } /* "dataRead.pyx":51 * return dataReadByte(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset) + * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) * elif signalDataType in (4, 5) and bitCount == 32: # float # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 4) or \ * (byteorder == 'big' and signalDataType == 5): @@ -2032,7 +2039,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, if (__pyx_t_3) { /* "dataRead.pyx":52 - * record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset) + * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) * elif signalDataType in (4, 5) and bitCount == 32: # float * if (byteorder == 'little' and signalDataType == 4) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 5): @@ -2075,7 +2082,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L11_bool_binop_done:; /* "dataRead.pyx":52 - * record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset) + * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) * elif signalDataType in (4, 5) and bitCount == 32: # float * if (byteorder == 'little' and signalDataType == 4) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 5): @@ -2106,7 +2113,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, goto __pyx_L0; /* "dataRead.pyx":52 - * record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset) + * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) * elif signalDataType in (4, 5) and bitCount == 32: # float * if (byteorder == 'little' and signalDataType == 4) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 5): @@ -2140,7 +2147,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":51 * return dataReadByte(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset) + * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) * elif signalDataType in (4, 5) and bitCount == 32: # float # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 4) or \ * (byteorder == 'big' and signalDataType == 5): @@ -2751,7 +2758,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): # <<<<<<<<<<<<<< * return dataReadUInt(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) */ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 91, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -2779,7 +2786,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): * return dataReadUInt(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) * else: # swap bytes */ __Pyx_XDECREF(__pyx_r); @@ -2787,11 +2794,11 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":93 * (byteorder == 'big' and signalDataType == 1): * return dataReadUInt(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) # <<<<<<<<<<<<<< + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) # <<<<<<<<<<<<<< * else: # swap bytes * return dataReadUInt(bita, RecordFormat, numberOfRecords, */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadUInt(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 92, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_dataReadUInt(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, __pyx_v_nBytes, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 92, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; @@ -2807,10 +2814,10 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, } /* "dataRead.pyx":95 - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) * else: # swap bytes * return dataReadUInt(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int */ /*else*/ { @@ -2819,11 +2826,11 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":96 * else: # swap bytes * return dataReadUInt(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) # <<<<<<<<<<<<<< + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) # <<<<<<<<<<<<<< * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int * if (byteorder == 'little' and signalDataType == 2) or \ */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadUInt(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 95, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_dataReadUInt(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, __pyx_v_nBytes, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 95, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; @@ -2841,7 +2848,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":97 * return dataReadUInt(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 2) or \ * (byteorder == 'big' and signalDataType == 3): @@ -2867,7 +2874,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, if (__pyx_t_3) { /* "dataRead.pyx":98 - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int * if (byteorder == 'little' and signalDataType == 2) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 3): @@ -2894,7 +2901,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * if (byteorder == 'little' and signalDataType == 2) or \ * (byteorder == 'big' and signalDataType == 3): # <<<<<<<<<<<<<< * return dataReadInt(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) */ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 99, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -2910,7 +2917,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L50_bool_binop_done:; /* "dataRead.pyx":98 - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int * if (byteorder == 'little' and signalDataType == 2) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 3): @@ -2922,7 +2929,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * if (byteorder == 'little' and signalDataType == 2) or \ * (byteorder == 'big' and signalDataType == 3): * return dataReadInt(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) * else: # swap bytes */ __Pyx_XDECREF(__pyx_r); @@ -2930,18 +2937,18 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":101 * (byteorder == 'big' and signalDataType == 3): * return dataReadInt(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) # <<<<<<<<<<<<<< + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) # <<<<<<<<<<<<<< * else: # swap bytes * return dataReadInt(bita, RecordFormat, numberOfRecords, */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadInt(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 100, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_dataReadInt(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, __pyx_v_nBytes, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 100, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; /* "dataRead.pyx":98 - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int * if (byteorder == 'little' and signalDataType == 2) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 3): @@ -2950,10 +2957,10 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, } /* "dataRead.pyx":103 - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) * else: # swap bytes * return dataReadInt(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long */ /*else*/ { @@ -2962,11 +2969,11 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":104 * else: # swap bytes * return dataReadInt(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) # <<<<<<<<<<<<<< + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) # <<<<<<<<<<<<<< * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long * if (byteorder == 'little' and signalDataType == 0) or \ */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadInt(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 103, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_dataReadInt(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, __pyx_v_nBytes, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 103, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; @@ -2975,7 +2982,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":97 * return dataReadUInt(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 2) or \ * (byteorder == 'big' and signalDataType == 3): @@ -2984,7 +2991,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":105 * return dataReadInt(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): @@ -3010,7 +3017,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, if (__pyx_t_3) { /* "dataRead.pyx":106 - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): @@ -3037,7 +3044,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): # <<<<<<<<<<<<<< * return dataReadULongLong(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) */ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 107, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -3053,7 +3060,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L57_bool_binop_done:; /* "dataRead.pyx":106 - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): @@ -3065,7 +3072,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): * return dataReadULongLong(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) * else: # swap bytes */ __Pyx_XDECREF(__pyx_r); @@ -3073,18 +3080,18 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":109 * (byteorder == 'big' and signalDataType == 1): * return dataReadULongLong(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) # <<<<<<<<<<<<<< + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) # <<<<<<<<<<<<<< * else: # swap bytes * return dataReadULongLong(bita, RecordFormat, numberOfRecords, */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadULongLong(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 108, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_dataReadULongLong(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, __pyx_v_nBytes, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 108, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; /* "dataRead.pyx":106 - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): @@ -3093,10 +3100,10 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, } /* "dataRead.pyx":111 - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) * else: # swap bytes * return dataReadULongLong(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long */ /*else*/ { @@ -3105,11 +3112,11 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":112 * else: # swap bytes * return dataReadULongLong(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) # <<<<<<<<<<<<<< + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) # <<<<<<<<<<<<<< * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long * if (byteorder == 'little' and signalDataType == 0) or \ */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadULongLong(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 111, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_dataReadULongLong(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, __pyx_v_nBytes, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 111, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; @@ -3118,7 +3125,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":105 * return dataReadInt(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): @@ -3127,7 +3134,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":113 * return dataReadULongLong(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): @@ -3153,7 +3160,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, if (__pyx_t_3) { /* "dataRead.pyx":114 - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): @@ -3180,7 +3187,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): # <<<<<<<<<<<<<< * return dataReadLongLong(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) */ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 115, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -3196,7 +3203,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L64_bool_binop_done:; /* "dataRead.pyx":114 - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): @@ -3208,7 +3215,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): * return dataReadLongLong(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) * else: # swap bytes */ __Pyx_XDECREF(__pyx_r); @@ -3216,18 +3223,18 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":117 * (byteorder == 'big' and signalDataType == 1): * return dataReadLongLong(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) # <<<<<<<<<<<<<< + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) # <<<<<<<<<<<<<< * else: # swap bytes * return dataReadLongLong(bita, RecordFormat, numberOfRecords, */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadLongLong(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 116, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_dataReadLongLong(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, __pyx_v_nBytes, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 116, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; /* "dataRead.pyx":114 - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): @@ -3236,10 +3243,10 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, } /* "dataRead.pyx":119 - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) * else: # swap bytes * return dataReadLongLong(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) * else: */ /*else*/ { @@ -3248,11 +3255,11 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":120 * else: # swap bytes * return dataReadLongLong(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) # <<<<<<<<<<<<<< + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) # <<<<<<<<<<<<<< * else: * return dataReadByte(bita, RecordFormat, numberOfRecords, */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadLongLong(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 119, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_dataReadLongLong(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, __pyx_v_nBytes, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 119, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; @@ -3261,7 +3268,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":113 * return dataReadULongLong(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): @@ -3269,10 +3276,10 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, } /* "dataRead.pyx":122 - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) + * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) * else: * return dataReadByte(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset) + * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) * else: # array */ /*else*/ { @@ -3281,11 +3288,11 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":123 * else: * return dataReadByte(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset) # <<<<<<<<<<<<<< + * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) # <<<<<<<<<<<<<< * else: # array * if (byteorder == 'little' and signalDataType in (0, 2, 4)) or \ */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadByte(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_posByteEnd, __pyx_v_bitCount, __pyx_v_bitOffset); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 122, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_dataReadByte(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_nBytes, __pyx_v_bitCount, __pyx_v_bitOffset); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 122, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; @@ -3302,7 +3309,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, } /* "dataRead.pyx":125 - * record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset) + * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) * else: # array * if (byteorder == 'little' and signalDataType in (0, 2, 4)) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType in (1, 3, 5)): @@ -3340,7 +3347,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * if (byteorder == 'little' and signalDataType in (0, 2, 4)) or \ * (byteorder == 'big' and signalDataType in (1, 3, 5)): # <<<<<<<<<<<<<< * return dataReadArray(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset, 0) + * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset, 0) */ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 126, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -3366,7 +3373,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L69_bool_binop_done:; /* "dataRead.pyx":125 - * record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset) + * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) * else: # array * if (byteorder == 'little' and signalDataType in (0, 2, 4)) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType in (1, 3, 5)): @@ -3378,7 +3385,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * if (byteorder == 'little' and signalDataType in (0, 2, 4)) or \ * (byteorder == 'big' and signalDataType in (1, 3, 5)): * return dataReadArray(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset, 0) + * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset, 0) * else: # swap bytes */ __Pyx_XDECREF(__pyx_r); @@ -3386,18 +3393,18 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":128 * (byteorder == 'big' and signalDataType in (1, 3, 5)): * return dataReadArray(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset, 0) # <<<<<<<<<<<<<< + * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset, 0) # <<<<<<<<<<<<<< * else: # swap bytes * return dataReadArray(bita, RecordFormat, numberOfRecords, */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadArray(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_posByteEnd, __pyx_v_bitCount, __pyx_v_bitOffset, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 127, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_dataReadArray(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_nBytes, __pyx_v_bitCount, __pyx_v_bitOffset, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 127, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; /* "dataRead.pyx":125 - * record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset) + * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) * else: # array * if (byteorder == 'little' and signalDataType in (0, 2, 4)) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType in (1, 3, 5)): @@ -3406,10 +3413,10 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, } /* "dataRead.pyx":130 - * record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset, 0) + * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset, 0) * else: # swap bytes * return dataReadArray(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset, 1) + * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset, 1) * */ /*else*/ { @@ -3418,11 +3425,11 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":131 * else: # swap bytes * return dataReadArray(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset, 1) # <<<<<<<<<<<<<< + * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset, 1) # <<<<<<<<<<<<<< * * */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadArray(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_posByteEnd, __pyx_v_bitCount, __pyx_v_bitOffset, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 130, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_dataReadArray(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_nBytes, __pyx_v_bitCount, __pyx_v_bitOffset, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 130, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; @@ -5539,15 +5546,14 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadShort(char const *__pyx * * cdef inline dataReadUInt(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): + * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): */ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_bitCount, unsigned char __pyx_v_bitOffset, unsigned char __pyx_v_swap) { +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_bitCount, unsigned char __pyx_v_bitOffset, unsigned long __pyx_v_nBytes, unsigned char __pyx_v_swap) { PyArrayObject *__pyx_v_buf = 0; unsigned PY_LONG_LONG __pyx_v_i; unsigned int __pyx_v_mask; unsigned int __pyx_v_temp4byte; - unsigned char __pyx_v_nBytes; char __pyx_v_temp4[4]; char __pyx_v_temp3[3]; __Pyx_LocalBuf_ND __pyx_pybuffernd_buf; @@ -5577,7 +5583,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ /* "dataRead.pyx":302 * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): + * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): * cdef np.ndarray[np.uint32_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array # <<<<<<<<<<<<<< * cdef unsigned long long i * cdef unsigned int mask = ((1 << bitCount) - 1) @@ -5621,7 +5627,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ * cdef unsigned long long i * cdef unsigned int mask = ((1 << bitCount) - 1) # <<<<<<<<<<<<<< * cdef unsigned int temp4byte = 0 - * cdef unsigned char nBytes = 0 + * cdef char temp4[4] */ __pyx_v_mask = ((1 << __pyx_v_bitCount) - 1); @@ -5629,64 +5635,14 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ * cdef unsigned long long i * cdef unsigned int mask = ((1 << bitCount) - 1) * cdef unsigned int temp4byte = 0 # <<<<<<<<<<<<<< - * cdef unsigned char nBytes = 0 - * cdef char temp4[4] - */ - __pyx_v_temp4byte = 0; - - /* "dataRead.pyx":306 - * cdef unsigned int mask = ((1 << bitCount) - 1) - * cdef unsigned int temp4byte = 0 - * cdef unsigned char nBytes = 0 # <<<<<<<<<<<<<< * cdef char temp4[4] * cdef char temp3[3] */ - __pyx_v_nBytes = 0; - - /* "dataRead.pyx":309 - * cdef char temp4[4] - * cdef char temp3[3] - * if bitCount + bitOffset > 24: # <<<<<<<<<<<<<< - * nBytes = 4 - * else: - */ - __pyx_t_6 = (((__pyx_v_bitCount + __pyx_v_bitOffset) > 24) != 0); - if (__pyx_t_6) { - - /* "dataRead.pyx":310 - * cdef char temp3[3] - * if bitCount + bitOffset > 24: - * nBytes = 4 # <<<<<<<<<<<<<< - * else: - * nBytes = 3 - */ - __pyx_v_nBytes = 4; + __pyx_v_temp4byte = 0; - /* "dataRead.pyx":309 + /* "dataRead.pyx":308 * cdef char temp4[4] * cdef char temp3[3] - * if bitCount + bitOffset > 24: # <<<<<<<<<<<<<< - * nBytes = 4 - * else: - */ - goto __pyx_L3; - } - - /* "dataRead.pyx":312 - * nBytes = 4 - * else: - * nBytes = 3 # <<<<<<<<<<<<<< - * if bitCount == 32: - * for i in range(numberOfRecords): - */ - /*else*/ { - __pyx_v_nBytes = 3; - } - __pyx_L3:; - - /* "dataRead.pyx":313 - * else: - * nBytes = 3 * if bitCount == 32: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) @@ -5694,8 +5650,8 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ __pyx_t_6 = ((__pyx_v_bitCount == 32) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":314 - * nBytes = 3 + /* "dataRead.pyx":309 + * cdef char temp3[3] * if bitCount == 32: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) @@ -5706,7 +5662,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":315 + /* "dataRead.pyx":310 * if bitCount == 32: * for i in range(numberOfRecords): * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) # <<<<<<<<<<<<<< @@ -5715,7 +5671,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ (void)(memcpy((&__pyx_v_temp4byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), 2)); - /* "dataRead.pyx":316 + /* "dataRead.pyx":311 * for i in range(numberOfRecords): * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) * buf[i] = temp4byte # <<<<<<<<<<<<<< @@ -5727,12 +5683,12 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ if (unlikely(__pyx_t_10 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 316, __pyx_L1_error) + __PYX_ERR(0, 311, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint32_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp4byte; } - /* "dataRead.pyx":317 + /* "dataRead.pyx":312 * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) * buf[i] = temp4byte * if swap == 0: # <<<<<<<<<<<<<< @@ -5742,7 +5698,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":318 + /* "dataRead.pyx":313 * buf[i] = temp4byte * if swap == 0: * return buf # <<<<<<<<<<<<<< @@ -5754,7 +5710,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ __pyx_r = ((PyObject *)__pyx_v_buf); goto __pyx_L0; - /* "dataRead.pyx":317 + /* "dataRead.pyx":312 * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) * buf[i] = temp4byte * if swap == 0: # <<<<<<<<<<<<<< @@ -5763,7 +5719,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ } - /* "dataRead.pyx":320 + /* "dataRead.pyx":315 * return buf * else: * return buf.byteswap() # <<<<<<<<<<<<<< @@ -5772,7 +5728,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ /*else*/ { __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_buf), __pyx_n_s_byteswap); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 320, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_buf), __pyx_n_s_byteswap); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 315, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) { @@ -5785,10 +5741,10 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ } } if (__pyx_t_3) { - __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 320, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 315, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; } else { - __pyx_t_4 = __Pyx_PyObject_CallNoArg(__pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 320, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_CallNoArg(__pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 315, __pyx_L1_error) } __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; @@ -5797,16 +5753,16 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ goto __pyx_L0; } - /* "dataRead.pyx":313 - * else: - * nBytes = 3 + /* "dataRead.pyx":308 + * cdef char temp4[4] + * cdef char temp3[3] * if bitCount == 32: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) */ } - /* "dataRead.pyx":321 + /* "dataRead.pyx":316 * else: * return buf.byteswap() * elif nBytes == 4: # <<<<<<<<<<<<<< @@ -5816,7 +5772,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ __pyx_t_6 = ((__pyx_v_nBytes == 4) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":322 + /* "dataRead.pyx":317 * return buf.byteswap() * elif nBytes == 4: * if swap == 0: # <<<<<<<<<<<<<< @@ -5826,7 +5782,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":323 + /* "dataRead.pyx":318 * elif nBytes == 4: * if swap == 0: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -5838,7 +5794,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":324 + /* "dataRead.pyx":319 * if swap == 0: * for i in range(numberOfRecords): * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -5847,7 +5803,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ (void)(memcpy((&__pyx_v_temp4byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":326 + /* "dataRead.pyx":321 * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -5857,7 +5813,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":327 + /* "dataRead.pyx":322 * # right shift * if bitOffset > 0: * temp4byte = temp4byte >> bitOffset # <<<<<<<<<<<<<< @@ -5866,7 +5822,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":326 + /* "dataRead.pyx":321 * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -5875,7 +5831,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ } - /* "dataRead.pyx":329 + /* "dataRead.pyx":324 * temp4byte = temp4byte >> bitOffset * # mask left part * if bitCount < 32: # <<<<<<<<<<<<<< @@ -5885,7 +5841,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ __pyx_t_6 = ((__pyx_v_bitCount < 32) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":330 + /* "dataRead.pyx":325 * # mask left part * if bitCount < 32: * temp4byte &= mask # <<<<<<<<<<<<<< @@ -5894,7 +5850,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ __pyx_v_temp4byte = (__pyx_v_temp4byte & __pyx_v_mask); - /* "dataRead.pyx":329 + /* "dataRead.pyx":324 * temp4byte = temp4byte >> bitOffset * # mask left part * if bitCount < 32: # <<<<<<<<<<<<<< @@ -5903,7 +5859,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ } - /* "dataRead.pyx":331 + /* "dataRead.pyx":326 * if bitCount < 32: * temp4byte &= mask * buf[i] = temp4byte # <<<<<<<<<<<<<< @@ -5915,22 +5871,22 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ if (unlikely(__pyx_t_12 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 331, __pyx_L1_error) + __PYX_ERR(0, 326, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint32_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp4byte; } - /* "dataRead.pyx":322 + /* "dataRead.pyx":317 * return buf.byteswap() * elif nBytes == 4: * if swap == 0: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) */ - goto __pyx_L8; + goto __pyx_L7; } - /* "dataRead.pyx":333 + /* "dataRead.pyx":328 * buf[i] = temp4byte * else: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -5943,7 +5899,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":334 + /* "dataRead.pyx":329 * else: * for i in range(numberOfRecords): * memcpy(&temp4, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -5952,7 +5908,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ (void)(memcpy((&__pyx_v_temp4), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":335 + /* "dataRead.pyx":330 * for i in range(numberOfRecords): * memcpy(&temp4, &bita[posByteBeg + record_byte_size * i], nBytes) * temp4byte = temp4[0]<<24 | temp4[1]<<16 | temp4[2]<<8 | temp4[3] # swap bytes # <<<<<<<<<<<<<< @@ -5961,7 +5917,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ __pyx_v_temp4byte = (((((__pyx_v_temp4[0]) << 24) | ((__pyx_v_temp4[1]) << 16)) | ((__pyx_v_temp4[2]) << 8)) | (__pyx_v_temp4[3])); - /* "dataRead.pyx":337 + /* "dataRead.pyx":332 * temp4byte = temp4[0]<<24 | temp4[1]<<16 | temp4[2]<<8 | temp4[3] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -5971,7 +5927,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":338 + /* "dataRead.pyx":333 * # right shift * if bitOffset > 0: * temp4byte = temp4byte >> bitOffset # <<<<<<<<<<<<<< @@ -5980,7 +5936,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":337 + /* "dataRead.pyx":332 * temp4byte = temp4[0]<<24 | temp4[1]<<16 | temp4[2]<<8 | temp4[3] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -5989,7 +5945,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ } - /* "dataRead.pyx":340 + /* "dataRead.pyx":335 * temp4byte = temp4byte >> bitOffset * # mask left part * if bitCount < 32: # <<<<<<<<<<<<<< @@ -5999,7 +5955,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ __pyx_t_6 = ((__pyx_v_bitCount < 32) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":341 + /* "dataRead.pyx":336 * # mask left part * if bitCount < 32: * temp4byte &= mask # <<<<<<<<<<<<<< @@ -6008,7 +5964,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ __pyx_v_temp4byte = (__pyx_v_temp4byte & __pyx_v_mask); - /* "dataRead.pyx":340 + /* "dataRead.pyx":335 * temp4byte = temp4byte >> bitOffset * # mask left part * if bitCount < 32: # <<<<<<<<<<<<<< @@ -6017,7 +5973,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ } - /* "dataRead.pyx":342 + /* "dataRead.pyx":337 * if bitCount < 32: * temp4byte &= mask * buf[i] = temp4byte # <<<<<<<<<<<<<< @@ -6029,14 +5985,14 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ if (unlikely(__pyx_t_13 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 342, __pyx_L1_error) + __PYX_ERR(0, 337, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint32_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp4byte; } } - __pyx_L8:; + __pyx_L7:; - /* "dataRead.pyx":343 + /* "dataRead.pyx":338 * temp4byte &= mask * buf[i] = temp4byte * return buf # <<<<<<<<<<<<<< @@ -6048,7 +6004,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ __pyx_r = ((PyObject *)__pyx_v_buf); goto __pyx_L0; - /* "dataRead.pyx":321 + /* "dataRead.pyx":316 * else: * return buf.byteswap() * elif nBytes == 4: # <<<<<<<<<<<<<< @@ -6057,7 +6013,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ } - /* "dataRead.pyx":345 + /* "dataRead.pyx":340 * return buf * else: # on 3 bytes * if swap == 0: # <<<<<<<<<<<<<< @@ -6068,7 +6024,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":346 + /* "dataRead.pyx":341 * else: # on 3 bytes * if swap == 0: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -6080,7 +6036,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":347 + /* "dataRead.pyx":342 * if swap == 0: * for i in range(numberOfRecords): * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -6089,7 +6045,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ (void)(memcpy((&__pyx_v_temp4byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":349 + /* "dataRead.pyx":344 * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -6099,7 +6055,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":350 + /* "dataRead.pyx":345 * # right shift * if bitOffset > 0: * temp4byte = temp4byte >> bitOffset # <<<<<<<<<<<<<< @@ -6108,7 +6064,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":349 + /* "dataRead.pyx":344 * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -6117,7 +6073,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ } - /* "dataRead.pyx":352 + /* "dataRead.pyx":347 * temp4byte = temp4byte >> bitOffset * # mask left part * if bitCount < 24: # <<<<<<<<<<<<<< @@ -6127,7 +6083,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ __pyx_t_6 = ((__pyx_v_bitCount < 24) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":353 + /* "dataRead.pyx":348 * # mask left part * if bitCount < 24: * temp4byte &= mask # <<<<<<<<<<<<<< @@ -6136,7 +6092,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ __pyx_v_temp4byte = (__pyx_v_temp4byte & __pyx_v_mask); - /* "dataRead.pyx":352 + /* "dataRead.pyx":347 * temp4byte = temp4byte >> bitOffset * # mask left part * if bitCount < 24: # <<<<<<<<<<<<<< @@ -6145,7 +6101,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ } - /* "dataRead.pyx":354 + /* "dataRead.pyx":349 * if bitCount < 24: * temp4byte &= mask * buf[i] = temp4byte # <<<<<<<<<<<<<< @@ -6157,22 +6113,22 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ if (unlikely(__pyx_t_14 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 354, __pyx_L1_error) + __PYX_ERR(0, 349, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint32_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp4byte; } - /* "dataRead.pyx":345 + /* "dataRead.pyx":340 * return buf * else: # on 3 bytes * if swap == 0: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) */ - goto __pyx_L17; + goto __pyx_L16; } - /* "dataRead.pyx":356 + /* "dataRead.pyx":351 * buf[i] = temp4byte * else: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -6185,7 +6141,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":357 + /* "dataRead.pyx":352 * else: * for i in range(numberOfRecords): * memcpy(&temp3, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -6194,7 +6150,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ (void)(memcpy((&__pyx_v_temp3), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":358 + /* "dataRead.pyx":353 * for i in range(numberOfRecords): * memcpy(&temp3, &bita[posByteBeg + record_byte_size * i], nBytes) * temp4byte = temp3[0]<<16 | temp3[1]<<8 | temp3[2] # swap bytes # <<<<<<<<<<<<<< @@ -6203,7 +6159,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ __pyx_v_temp4byte = ((((__pyx_v_temp3[0]) << 16) | ((__pyx_v_temp3[1]) << 8)) | (__pyx_v_temp3[2])); - /* "dataRead.pyx":360 + /* "dataRead.pyx":355 * temp4byte = temp3[0]<<16 | temp3[1]<<8 | temp3[2] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -6213,7 +6169,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":361 + /* "dataRead.pyx":356 * # right shift * if bitOffset > 0: * temp4byte = temp4byte >> bitOffset # <<<<<<<<<<<<<< @@ -6222,7 +6178,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":360 + /* "dataRead.pyx":355 * temp4byte = temp3[0]<<16 | temp3[1]<<8 | temp3[2] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -6231,7 +6187,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ } - /* "dataRead.pyx":363 + /* "dataRead.pyx":358 * temp4byte = temp4byte >> bitOffset * # mask left part * if bitCount < 24: # <<<<<<<<<<<<<< @@ -6241,7 +6197,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ __pyx_t_6 = ((__pyx_v_bitCount < 24) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":364 + /* "dataRead.pyx":359 * # mask left part * if bitCount < 24: * temp4byte &= mask # <<<<<<<<<<<<<< @@ -6250,7 +6206,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ __pyx_v_temp4byte = (__pyx_v_temp4byte & __pyx_v_mask); - /* "dataRead.pyx":363 + /* "dataRead.pyx":358 * temp4byte = temp4byte >> bitOffset * # mask left part * if bitCount < 24: # <<<<<<<<<<<<<< @@ -6259,7 +6215,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ */ } - /* "dataRead.pyx":365 + /* "dataRead.pyx":360 * if bitCount < 24: * temp4byte &= mask * buf[i] = temp4byte # <<<<<<<<<<<<<< @@ -6271,14 +6227,14 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ if (unlikely(__pyx_t_15 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 365, __pyx_L1_error) + __PYX_ERR(0, 360, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint32_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_15, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp4byte; } } - __pyx_L17:; + __pyx_L16:; - /* "dataRead.pyx":366 + /* "dataRead.pyx":361 * temp4byte &= mask * buf[i] = temp4byte * return buf # <<<<<<<<<<<<<< @@ -6296,7 +6252,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ * * cdef inline dataReadUInt(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): + * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): */ /* function exit code */ @@ -6323,20 +6279,19 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ return __pyx_r; } -/* "dataRead.pyx":369 +/* "dataRead.pyx":364 * * * cdef inline dataReadInt(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): + * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): */ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_bitCount, unsigned char __pyx_v_bitOffset, unsigned char __pyx_v_swap) { +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_bitCount, unsigned char __pyx_v_bitOffset, unsigned long __pyx_v_nBytes, unsigned char __pyx_v_swap) { PyArrayObject *__pyx_v_buf = 0; unsigned PY_LONG_LONG __pyx_v_i; int __pyx_v_mask; int __pyx_v_temp4byte; - unsigned char __pyx_v_nBytes; int __pyx_v_signBit; int __pyx_v_signBitMask; int __pyx_v_signExtend; @@ -6367,40 +6322,40 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_pybuffernd_buf.data = NULL; __pyx_pybuffernd_buf.rcbuffer = &__pyx_pybuffer_buf; - /* "dataRead.pyx":372 + /* "dataRead.pyx":367 * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): + * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): * cdef np.ndarray[np.int32_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array # <<<<<<<<<<<<<< * cdef unsigned long long i * cdef int mask = ((1 << bitCount) - 1) */ - __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 372, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 367, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 372, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 367, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_numberOfRecords); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 372, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_numberOfRecords); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 367, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 372, __pyx_L1_error) + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 367, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 372, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 367, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 372, __pyx_L1_error) - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 372, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 367, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 367, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 372, __pyx_L1_error) + if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 367, __pyx_L1_error) __pyx_t_5 = ((PyArrayObject *)__pyx_t_4); { __Pyx_BufFmt_StackElem __pyx_stack[1]; if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_buf.rcbuffer->pybuffer, (PyObject*)__pyx_t_5, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int32_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) { __pyx_v_buf = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf = NULL; - __PYX_ERR(0, 372, __pyx_L1_error) + __PYX_ERR(0, 367, __pyx_L1_error) } else {__pyx_pybuffernd_buf.diminfo[0].strides = __pyx_pybuffernd_buf.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_buf.diminfo[0].shape = __pyx_pybuffernd_buf.rcbuffer->pybuffer.shape[0]; } } @@ -6408,44 +6363,35 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_v_buf = ((PyArrayObject *)__pyx_t_4); __pyx_t_4 = 0; - /* "dataRead.pyx":374 + /* "dataRead.pyx":369 * cdef np.ndarray[np.int32_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array * cdef unsigned long long i * cdef int mask = ((1 << bitCount) - 1) # <<<<<<<<<<<<<< * cdef int temp4byte = 0 - * cdef unsigned char nBytes = 0 + * cdef int signBit = 0 */ __pyx_v_mask = ((1 << __pyx_v_bitCount) - 1); - /* "dataRead.pyx":375 + /* "dataRead.pyx":370 * cdef unsigned long long i * cdef int mask = ((1 << bitCount) - 1) * cdef int temp4byte = 0 # <<<<<<<<<<<<<< - * cdef unsigned char nBytes = 0 * cdef int signBit = 0 + * cdef int signBitMask = (1 << (bitCount-1)) */ __pyx_v_temp4byte = 0; - /* "dataRead.pyx":376 + /* "dataRead.pyx":371 * cdef int mask = ((1 << bitCount) - 1) * cdef int temp4byte = 0 - * cdef unsigned char nBytes = 0 # <<<<<<<<<<<<<< - * cdef int signBit = 0 - * cdef int signBitMask = (1 << (bitCount-1)) - */ - __pyx_v_nBytes = 0; - - /* "dataRead.pyx":377 - * cdef int temp4byte = 0 - * cdef unsigned char nBytes = 0 * cdef int signBit = 0 # <<<<<<<<<<<<<< * cdef int signBitMask = (1 << (bitCount-1)) * cdef int signExtend = ((1 << (32 - bitCount)) - 1) << bitCount */ __pyx_v_signBit = 0; - /* "dataRead.pyx":378 - * cdef unsigned char nBytes = 0 + /* "dataRead.pyx":372 + * cdef int temp4byte = 0 * cdef int signBit = 0 * cdef int signBitMask = (1 << (bitCount-1)) # <<<<<<<<<<<<<< * cdef int signExtend = ((1 << (32 - bitCount)) - 1) << bitCount @@ -6453,7 +6399,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ __pyx_v_signBitMask = (1 << (__pyx_v_bitCount - 1)); - /* "dataRead.pyx":379 + /* "dataRead.pyx":373 * cdef int signBit = 0 * cdef int signBitMask = (1 << (bitCount-1)) * cdef int signExtend = ((1 << (32 - bitCount)) - 1) << bitCount # <<<<<<<<<<<<<< @@ -6462,50 +6408,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ __pyx_v_signExtend = (((1 << (32 - __pyx_v_bitCount)) - 1) << __pyx_v_bitCount); - /* "dataRead.pyx":382 - * cdef char temp4[4] - * cdef char temp3[3] - * if bitCount + bitOffset > 24: # <<<<<<<<<<<<<< - * nBytes = 4 - * else: - */ - __pyx_t_6 = (((__pyx_v_bitCount + __pyx_v_bitOffset) > 24) != 0); - if (__pyx_t_6) { - - /* "dataRead.pyx":383 - * cdef char temp3[3] - * if bitCount + bitOffset > 24: - * nBytes = 4 # <<<<<<<<<<<<<< - * else: - * nBytes = 3 - */ - __pyx_v_nBytes = 4; - - /* "dataRead.pyx":382 + /* "dataRead.pyx":376 * cdef char temp4[4] * cdef char temp3[3] - * if bitCount + bitOffset > 24: # <<<<<<<<<<<<<< - * nBytes = 4 - * else: - */ - goto __pyx_L3; - } - - /* "dataRead.pyx":385 - * nBytes = 4 - * else: - * nBytes = 3 # <<<<<<<<<<<<<< - * if bitCount == 32: - * for i in range(numberOfRecords): - */ - /*else*/ { - __pyx_v_nBytes = 3; - } - __pyx_L3:; - - /* "dataRead.pyx":386 - * else: - * nBytes = 3 * if bitCount == 32: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) @@ -6513,8 +6418,8 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_t_6 = ((__pyx_v_bitCount == 32) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":387 - * nBytes = 3 + /* "dataRead.pyx":377 + * cdef char temp3[3] * if bitCount == 32: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) @@ -6525,7 +6430,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":388 + /* "dataRead.pyx":378 * if bitCount == 32: * for i in range(numberOfRecords): * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) # <<<<<<<<<<<<<< @@ -6534,7 +6439,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ (void)(memcpy((&__pyx_v_temp4byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), 2)); - /* "dataRead.pyx":389 + /* "dataRead.pyx":379 * for i in range(numberOfRecords): * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) * buf[i] = temp4byte # <<<<<<<<<<<<<< @@ -6546,12 +6451,12 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v if (unlikely(__pyx_t_10 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 389, __pyx_L1_error) + __PYX_ERR(0, 379, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int32_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp4byte; } - /* "dataRead.pyx":390 + /* "dataRead.pyx":380 * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) * buf[i] = temp4byte * if swap == 0: # <<<<<<<<<<<<<< @@ -6561,7 +6466,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":391 + /* "dataRead.pyx":381 * buf[i] = temp4byte * if swap == 0: * return buf # <<<<<<<<<<<<<< @@ -6573,7 +6478,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_r = ((PyObject *)__pyx_v_buf); goto __pyx_L0; - /* "dataRead.pyx":390 + /* "dataRead.pyx":380 * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) * buf[i] = temp4byte * if swap == 0: # <<<<<<<<<<<<<< @@ -6582,7 +6487,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ } - /* "dataRead.pyx":393 + /* "dataRead.pyx":383 * return buf * else: * return buf.byteswap() # <<<<<<<<<<<<<< @@ -6591,7 +6496,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ /*else*/ { __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_buf), __pyx_n_s_byteswap); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 393, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_buf), __pyx_n_s_byteswap); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 383, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) { @@ -6604,10 +6509,10 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v } } if (__pyx_t_3) { - __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 393, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 383, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; } else { - __pyx_t_4 = __Pyx_PyObject_CallNoArg(__pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 393, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_CallNoArg(__pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 383, __pyx_L1_error) } __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; @@ -6616,16 +6521,16 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v goto __pyx_L0; } - /* "dataRead.pyx":386 - * else: - * nBytes = 3 + /* "dataRead.pyx":376 + * cdef char temp4[4] + * cdef char temp3[3] * if bitCount == 32: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) */ } - /* "dataRead.pyx":394 + /* "dataRead.pyx":384 * else: * return buf.byteswap() * elif nBytes == 4: # <<<<<<<<<<<<<< @@ -6635,7 +6540,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_t_6 = ((__pyx_v_nBytes == 4) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":395 + /* "dataRead.pyx":385 * return buf.byteswap() * elif nBytes == 4: * if swap == 0: # <<<<<<<<<<<<<< @@ -6645,7 +6550,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":396 + /* "dataRead.pyx":386 * elif nBytes == 4: * if swap == 0: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -6657,7 +6562,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":397 + /* "dataRead.pyx":387 * if swap == 0: * for i in range(numberOfRecords): * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -6666,7 +6571,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ (void)(memcpy((&__pyx_v_temp4byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":399 + /* "dataRead.pyx":389 * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -6676,7 +6581,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":400 + /* "dataRead.pyx":390 * # right shift * if bitOffset > 0: * temp4byte = temp4byte >> bitOffset # <<<<<<<<<<<<<< @@ -6685,7 +6590,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":399 + /* "dataRead.pyx":389 * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -6694,7 +6599,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ } - /* "dataRead.pyx":402 + /* "dataRead.pyx":392 * temp4byte = temp4byte >> bitOffset * # mask left part * if bitCount < 32: # <<<<<<<<<<<<<< @@ -6704,7 +6609,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_t_6 = ((__pyx_v_bitCount < 32) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":403 + /* "dataRead.pyx":393 * # mask left part * if bitCount < 32: * temp4byte &= mask # <<<<<<<<<<<<<< @@ -6713,7 +6618,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ __pyx_v_temp4byte = (__pyx_v_temp4byte & __pyx_v_mask); - /* "dataRead.pyx":402 + /* "dataRead.pyx":392 * temp4byte = temp4byte >> bitOffset * # mask left part * if bitCount < 32: # <<<<<<<<<<<<<< @@ -6722,7 +6627,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ } - /* "dataRead.pyx":404 + /* "dataRead.pyx":394 * if bitCount < 32: * temp4byte &= mask * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed # <<<<<<<<<<<<<< @@ -6731,7 +6636,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ __pyx_v_signBit = (__pyx_v_temp4byte & __pyx_v_signBitMask); - /* "dataRead.pyx":405 + /* "dataRead.pyx":395 * temp4byte &= mask * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -6741,7 +6646,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_t_6 = (__pyx_v_signBit != 0); if (__pyx_t_6) { - /* "dataRead.pyx":406 + /* "dataRead.pyx":396 * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed * if signBit: # negative value, sign extend * temp4byte |= signExtend # <<<<<<<<<<<<<< @@ -6750,7 +6655,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ __pyx_v_temp4byte = (__pyx_v_temp4byte | __pyx_v_signExtend); - /* "dataRead.pyx":405 + /* "dataRead.pyx":395 * temp4byte &= mask * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -6759,7 +6664,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ } - /* "dataRead.pyx":407 + /* "dataRead.pyx":397 * if signBit: # negative value, sign extend * temp4byte |= signExtend * buf[i] = temp4byte # <<<<<<<<<<<<<< @@ -6771,22 +6676,22 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v if (unlikely(__pyx_t_12 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 407, __pyx_L1_error) + __PYX_ERR(0, 397, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int32_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp4byte; } - /* "dataRead.pyx":395 + /* "dataRead.pyx":385 * return buf.byteswap() * elif nBytes == 4: * if swap == 0: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) */ - goto __pyx_L8; + goto __pyx_L7; } - /* "dataRead.pyx":409 + /* "dataRead.pyx":399 * buf[i] = temp4byte * else: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -6799,7 +6704,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":410 + /* "dataRead.pyx":400 * else: * for i in range(numberOfRecords): * memcpy(&temp4, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -6808,7 +6713,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ (void)(memcpy((&__pyx_v_temp4), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":411 + /* "dataRead.pyx":401 * for i in range(numberOfRecords): * memcpy(&temp4, &bita[posByteBeg + record_byte_size * i], nBytes) * temp4byte = temp4[0]<<24 | temp4[1]<<16 | temp4[2]<<8 | temp4[3] # swap bytes # <<<<<<<<<<<<<< @@ -6817,7 +6722,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ __pyx_v_temp4byte = (((((__pyx_v_temp4[0]) << 24) | ((__pyx_v_temp4[1]) << 16)) | ((__pyx_v_temp4[2]) << 8)) | (__pyx_v_temp4[3])); - /* "dataRead.pyx":413 + /* "dataRead.pyx":403 * temp4byte = temp4[0]<<24 | temp4[1]<<16 | temp4[2]<<8 | temp4[3] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -6827,7 +6732,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":414 + /* "dataRead.pyx":404 * # right shift * if bitOffset > 0: * temp4byte = temp4byte >> bitOffset # <<<<<<<<<<<<<< @@ -6836,7 +6741,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":413 + /* "dataRead.pyx":403 * temp4byte = temp4[0]<<24 | temp4[1]<<16 | temp4[2]<<8 | temp4[3] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -6845,7 +6750,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ } - /* "dataRead.pyx":416 + /* "dataRead.pyx":406 * temp4byte = temp4byte >> bitOffset * # mask left part * if bitCount < 32: # <<<<<<<<<<<<<< @@ -6855,7 +6760,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_t_6 = ((__pyx_v_bitCount < 32) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":417 + /* "dataRead.pyx":407 * # mask left part * if bitCount < 32: * temp4byte &= mask # <<<<<<<<<<<<<< @@ -6864,7 +6769,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ __pyx_v_temp4byte = (__pyx_v_temp4byte & __pyx_v_mask); - /* "dataRead.pyx":416 + /* "dataRead.pyx":406 * temp4byte = temp4byte >> bitOffset * # mask left part * if bitCount < 32: # <<<<<<<<<<<<<< @@ -6873,7 +6778,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ } - /* "dataRead.pyx":418 + /* "dataRead.pyx":408 * if bitCount < 32: * temp4byte &= mask * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed # <<<<<<<<<<<<<< @@ -6882,7 +6787,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ __pyx_v_signBit = (__pyx_v_temp4byte & __pyx_v_signBitMask); - /* "dataRead.pyx":419 + /* "dataRead.pyx":409 * temp4byte &= mask * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -6892,7 +6797,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_t_6 = (__pyx_v_signBit != 0); if (__pyx_t_6) { - /* "dataRead.pyx":420 + /* "dataRead.pyx":410 * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed * if signBit: # negative value, sign extend * temp4byte |= signExtend # <<<<<<<<<<<<<< @@ -6901,7 +6806,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ __pyx_v_temp4byte = (__pyx_v_temp4byte | __pyx_v_signExtend); - /* "dataRead.pyx":419 + /* "dataRead.pyx":409 * temp4byte &= mask * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -6910,7 +6815,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ } - /* "dataRead.pyx":421 + /* "dataRead.pyx":411 * if signBit: # negative value, sign extend * temp4byte |= signExtend * buf[i] = temp4byte # <<<<<<<<<<<<<< @@ -6922,14 +6827,14 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v if (unlikely(__pyx_t_13 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 421, __pyx_L1_error) + __PYX_ERR(0, 411, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int32_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp4byte; } } - __pyx_L8:; + __pyx_L7:; - /* "dataRead.pyx":422 + /* "dataRead.pyx":412 * temp4byte |= signExtend * buf[i] = temp4byte * return buf # <<<<<<<<<<<<<< @@ -6941,7 +6846,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_r = ((PyObject *)__pyx_v_buf); goto __pyx_L0; - /* "dataRead.pyx":394 + /* "dataRead.pyx":384 * else: * return buf.byteswap() * elif nBytes == 4: # <<<<<<<<<<<<<< @@ -6950,7 +6855,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ } - /* "dataRead.pyx":424 + /* "dataRead.pyx":414 * return buf * else: # on 3 bytes * if swap == 0: # <<<<<<<<<<<<<< @@ -6961,7 +6866,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":425 + /* "dataRead.pyx":415 * else: # on 3 bytes * if swap == 0: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -6973,7 +6878,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":426 + /* "dataRead.pyx":416 * if swap == 0: * for i in range(numberOfRecords): * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -6982,7 +6887,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ (void)(memcpy((&__pyx_v_temp4byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":428 + /* "dataRead.pyx":418 * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -6992,7 +6897,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":429 + /* "dataRead.pyx":419 * # right shift * if bitOffset > 0: * temp4byte = temp4byte >> bitOffset # <<<<<<<<<<<<<< @@ -7001,7 +6906,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":428 + /* "dataRead.pyx":418 * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -7010,7 +6915,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ } - /* "dataRead.pyx":431 + /* "dataRead.pyx":421 * temp4byte = temp4byte >> bitOffset * # mask left part * if bitCount < 24: # <<<<<<<<<<<<<< @@ -7020,7 +6925,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_t_6 = ((__pyx_v_bitCount < 24) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":432 + /* "dataRead.pyx":422 * # mask left part * if bitCount < 24: * temp4byte &= mask # <<<<<<<<<<<<<< @@ -7029,7 +6934,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ __pyx_v_temp4byte = (__pyx_v_temp4byte & __pyx_v_mask); - /* "dataRead.pyx":431 + /* "dataRead.pyx":421 * temp4byte = temp4byte >> bitOffset * # mask left part * if bitCount < 24: # <<<<<<<<<<<<<< @@ -7038,7 +6943,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ } - /* "dataRead.pyx":433 + /* "dataRead.pyx":423 * if bitCount < 24: * temp4byte &= mask * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed # <<<<<<<<<<<<<< @@ -7047,7 +6952,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ __pyx_v_signBit = (__pyx_v_temp4byte & __pyx_v_signBitMask); - /* "dataRead.pyx":434 + /* "dataRead.pyx":424 * temp4byte &= mask * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -7057,7 +6962,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_t_6 = (__pyx_v_signBit != 0); if (__pyx_t_6) { - /* "dataRead.pyx":435 + /* "dataRead.pyx":425 * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed * if signBit: # negative value, sign extend * temp4byte |= signExtend # <<<<<<<<<<<<<< @@ -7066,7 +6971,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ __pyx_v_temp4byte = (__pyx_v_temp4byte | __pyx_v_signExtend); - /* "dataRead.pyx":434 + /* "dataRead.pyx":424 * temp4byte &= mask * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -7075,7 +6980,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ } - /* "dataRead.pyx":436 + /* "dataRead.pyx":426 * if signBit: # negative value, sign extend * temp4byte |= signExtend * buf[i] = temp4byte # <<<<<<<<<<<<<< @@ -7087,22 +6992,22 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v if (unlikely(__pyx_t_14 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 436, __pyx_L1_error) + __PYX_ERR(0, 426, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int32_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp4byte; } - /* "dataRead.pyx":424 + /* "dataRead.pyx":414 * return buf * else: # on 3 bytes * if swap == 0: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) */ - goto __pyx_L19; + goto __pyx_L18; } - /* "dataRead.pyx":438 + /* "dataRead.pyx":428 * buf[i] = temp4byte * else: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -7115,7 +7020,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":439 + /* "dataRead.pyx":429 * else: * for i in range(numberOfRecords): * memcpy(&temp3, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -7124,7 +7029,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ (void)(memcpy((&__pyx_v_temp3), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":440 + /* "dataRead.pyx":430 * for i in range(numberOfRecords): * memcpy(&temp3, &bita[posByteBeg + record_byte_size * i], nBytes) * temp4byte = temp3[0]<<16 | temp3[1]<<8 | temp3[2] # swap bytes # <<<<<<<<<<<<<< @@ -7133,7 +7038,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ __pyx_v_temp4byte = ((((__pyx_v_temp3[0]) << 16) | ((__pyx_v_temp3[1]) << 8)) | (__pyx_v_temp3[2])); - /* "dataRead.pyx":442 + /* "dataRead.pyx":432 * temp4byte = temp3[0]<<16 | temp3[1]<<8 | temp3[2] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -7143,7 +7048,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":443 + /* "dataRead.pyx":433 * # right shift * if bitOffset > 0: * temp4byte = temp4byte >> bitOffset # <<<<<<<<<<<<<< @@ -7152,7 +7057,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":442 + /* "dataRead.pyx":432 * temp4byte = temp3[0]<<16 | temp3[1]<<8 | temp3[2] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -7161,7 +7066,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ } - /* "dataRead.pyx":445 + /* "dataRead.pyx":435 * temp4byte = temp4byte >> bitOffset * # mask left part * if bitCount < 24: # <<<<<<<<<<<<<< @@ -7171,7 +7076,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_t_6 = ((__pyx_v_bitCount < 24) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":446 + /* "dataRead.pyx":436 * # mask left part * if bitCount < 24: * temp4byte &= mask # <<<<<<<<<<<<<< @@ -7180,7 +7085,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ __pyx_v_temp4byte = (__pyx_v_temp4byte & __pyx_v_mask); - /* "dataRead.pyx":445 + /* "dataRead.pyx":435 * temp4byte = temp4byte >> bitOffset * # mask left part * if bitCount < 24: # <<<<<<<<<<<<<< @@ -7189,7 +7094,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ } - /* "dataRead.pyx":447 + /* "dataRead.pyx":437 * if bitCount < 24: * temp4byte &= mask * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed # <<<<<<<<<<<<<< @@ -7198,7 +7103,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ __pyx_v_signBit = (__pyx_v_temp4byte & __pyx_v_signBitMask); - /* "dataRead.pyx":448 + /* "dataRead.pyx":438 * temp4byte &= mask * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -7208,7 +7113,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_t_6 = (__pyx_v_signBit != 0); if (__pyx_t_6) { - /* "dataRead.pyx":449 + /* "dataRead.pyx":439 * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed * if signBit: # negative value, sign extend * temp4byte |= signExtend # <<<<<<<<<<<<<< @@ -7217,7 +7122,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ __pyx_v_temp4byte = (__pyx_v_temp4byte | __pyx_v_signExtend); - /* "dataRead.pyx":448 + /* "dataRead.pyx":438 * temp4byte &= mask * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -7226,7 +7131,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v */ } - /* "dataRead.pyx":450 + /* "dataRead.pyx":440 * if signBit: # negative value, sign extend * temp4byte |= signExtend * buf[i] = temp4byte # <<<<<<<<<<<<<< @@ -7238,14 +7143,14 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v if (unlikely(__pyx_t_15 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 450, __pyx_L1_error) + __PYX_ERR(0, 440, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int32_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_15, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp4byte; } } - __pyx_L19:; + __pyx_L18:; - /* "dataRead.pyx":451 + /* "dataRead.pyx":441 * temp4byte |= signExtend * buf[i] = temp4byte * return buf # <<<<<<<<<<<<<< @@ -7258,12 +7163,12 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v goto __pyx_L0; } - /* "dataRead.pyx":369 + /* "dataRead.pyx":364 * * * cdef inline dataReadInt(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): + * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): */ /* function exit code */ @@ -7290,20 +7195,19 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v return __pyx_r; } -/* "dataRead.pyx":453 +/* "dataRead.pyx":443 * return buf * * cdef inline dataReadULongLong(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): + * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): */ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_bitCount, unsigned char __pyx_v_bitOffset, unsigned char __pyx_v_swap) { +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_bitCount, unsigned char __pyx_v_bitOffset, unsigned long __pyx_v_nBytes, unsigned char __pyx_v_swap) { PyArrayObject *__pyx_v_buf = 0; unsigned PY_LONG_LONG __pyx_v_i; unsigned PY_LONG_LONG __pyx_v_mask; unsigned PY_LONG_LONG __pyx_v_temp8byte; - unsigned char __pyx_v_nBytes; char __pyx_v_temp8[8]; char __pyx_v_temp7[7]; char __pyx_v_temp6[6]; @@ -7337,40 +7241,40 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_pybuffernd_buf.data = NULL; __pyx_pybuffernd_buf.rcbuffer = &__pyx_pybuffer_buf; - /* "dataRead.pyx":456 + /* "dataRead.pyx":446 * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): + * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): * cdef np.ndarray[np.uint64_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array # <<<<<<<<<<<<<< * cdef unsigned long long i * cdef unsigned long long mask = ((1 << bitCount) - 1) */ - __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 456, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 446, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 456, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 446, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_numberOfRecords); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 456, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_numberOfRecords); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 446, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 456, __pyx_L1_error) + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 446, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 456, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 446, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 456, __pyx_L1_error) - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 456, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 446, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 446, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 456, __pyx_L1_error) + if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 446, __pyx_L1_error) __pyx_t_5 = ((PyArrayObject *)__pyx_t_4); { __Pyx_BufFmt_StackElem __pyx_stack[1]; if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_buf.rcbuffer->pybuffer, (PyObject*)__pyx_t_5, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) { __pyx_v_buf = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf = NULL; - __PYX_ERR(0, 456, __pyx_L1_error) + __PYX_ERR(0, 446, __pyx_L1_error) } else {__pyx_pybuffernd_buf.diminfo[0].strides = __pyx_pybuffernd_buf.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_buf.diminfo[0].shape = __pyx_pybuffernd_buf.rcbuffer->pybuffer.shape[0]; } } @@ -7378,64 +7282,27 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_v_buf = ((PyArrayObject *)__pyx_t_4); __pyx_t_4 = 0; - /* "dataRead.pyx":458 + /* "dataRead.pyx":448 * cdef np.ndarray[np.uint64_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array * cdef unsigned long long i * cdef unsigned long long mask = ((1 << bitCount) - 1) # <<<<<<<<<<<<<< * cdef unsigned long long temp8byte = 0 - * cdef unsigned char nBytes = bitCount + bitOffset // 8 + * cdef char temp8[8] */ __pyx_v_mask = ((1 << __pyx_v_bitCount) - 1); - /* "dataRead.pyx":459 + /* "dataRead.pyx":449 * cdef unsigned long long i * cdef unsigned long long mask = ((1 << bitCount) - 1) * cdef unsigned long long temp8byte = 0 # <<<<<<<<<<<<<< - * cdef unsigned char nBytes = bitCount + bitOffset // 8 - * cdef char temp8[8] - */ - __pyx_v_temp8byte = 0; - - /* "dataRead.pyx":460 - * cdef unsigned long long mask = ((1 << bitCount) - 1) - * cdef unsigned long long temp8byte = 0 - * cdef unsigned char nBytes = bitCount + bitOffset // 8 # <<<<<<<<<<<<<< * cdef char temp8[8] * cdef char temp7[7] */ - __pyx_v_nBytes = (__pyx_v_bitCount + __Pyx_div_long(__pyx_v_bitOffset, 8)); - - /* "dataRead.pyx":465 - * cdef char temp6[6] - * cdef char temp5[5] - * if bitCount + bitOffset % 8 > 0: # <<<<<<<<<<<<<< - * nBytes += 1 - * if bitCount == 64: - */ - __pyx_t_6 = (((__pyx_v_bitCount + __Pyx_mod_long(__pyx_v_bitOffset, 8)) > 0) != 0); - if (__pyx_t_6) { - - /* "dataRead.pyx":466 - * cdef char temp5[5] - * if bitCount + bitOffset % 8 > 0: - * nBytes += 1 # <<<<<<<<<<<<<< - * if bitCount == 64: - * for i in range(numberOfRecords): - */ - __pyx_v_nBytes = (__pyx_v_nBytes + 1); + __pyx_v_temp8byte = 0; - /* "dataRead.pyx":465 + /* "dataRead.pyx":454 * cdef char temp6[6] * cdef char temp5[5] - * if bitCount + bitOffset % 8 > 0: # <<<<<<<<<<<<<< - * nBytes += 1 - * if bitCount == 64: - */ - } - - /* "dataRead.pyx":467 - * if bitCount + bitOffset % 8 > 0: - * nBytes += 1 * if bitCount == 64: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) @@ -7443,8 +7310,8 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_bitCount == 64) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":468 - * nBytes += 1 + /* "dataRead.pyx":455 + * cdef char temp5[5] * if bitCount == 64: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) @@ -7455,7 +7322,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":469 + /* "dataRead.pyx":456 * if bitCount == 64: * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -7464,7 +7331,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":470 + /* "dataRead.pyx":457 * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) * buf[i] = temp8byte # <<<<<<<<<<<<<< @@ -7476,12 +7343,12 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ if (unlikely(__pyx_t_10 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 470, __pyx_L1_error) + __PYX_ERR(0, 457, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp8byte; } - /* "dataRead.pyx":471 + /* "dataRead.pyx":458 * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) * buf[i] = temp8byte * if swap == 0: # <<<<<<<<<<<<<< @@ -7491,7 +7358,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":472 + /* "dataRead.pyx":459 * buf[i] = temp8byte * if swap == 0: * return buf # <<<<<<<<<<<<<< @@ -7503,7 +7370,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_r = ((PyObject *)__pyx_v_buf); goto __pyx_L0; - /* "dataRead.pyx":471 + /* "dataRead.pyx":458 * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) * buf[i] = temp8byte * if swap == 0: # <<<<<<<<<<<<<< @@ -7512,7 +7379,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ } - /* "dataRead.pyx":474 + /* "dataRead.pyx":461 * return buf * else: * return buf.byteswap() # <<<<<<<<<<<<<< @@ -7521,7 +7388,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ /*else*/ { __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_buf), __pyx_n_s_byteswap); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 474, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_buf), __pyx_n_s_byteswap); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 461, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) { @@ -7534,10 +7401,10 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ } } if (__pyx_t_3) { - __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 474, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 461, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; } else { - __pyx_t_4 = __Pyx_PyObject_CallNoArg(__pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 474, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_CallNoArg(__pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 461, __pyx_L1_error) } __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; @@ -7546,16 +7413,16 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ goto __pyx_L0; } - /* "dataRead.pyx":467 - * if bitCount + bitOffset % 8 > 0: - * nBytes += 1 + /* "dataRead.pyx":454 + * cdef char temp6[6] + * cdef char temp5[5] * if bitCount == 64: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) */ } - /* "dataRead.pyx":475 + /* "dataRead.pyx":462 * else: * return buf.byteswap() * elif nBytes == 8: # <<<<<<<<<<<<<< @@ -7565,7 +7432,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_nBytes == 8) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":476 + /* "dataRead.pyx":463 * return buf.byteswap() * elif nBytes == 8: * if swap == 0: # <<<<<<<<<<<<<< @@ -7575,7 +7442,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":477 + /* "dataRead.pyx":464 * elif nBytes == 8: * if swap == 0: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -7587,7 +7454,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":478 + /* "dataRead.pyx":465 * if swap == 0: * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -7596,7 +7463,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":480 + /* "dataRead.pyx":467 * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -7606,7 +7473,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":481 + /* "dataRead.pyx":468 * # right shift * if bitOffset > 0: * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< @@ -7615,7 +7482,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":480 + /* "dataRead.pyx":467 * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -7624,7 +7491,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ } - /* "dataRead.pyx":483 + /* "dataRead.pyx":470 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 64: # <<<<<<<<<<<<<< @@ -7634,7 +7501,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_bitCount < 64) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":484 + /* "dataRead.pyx":471 * # mask left part * if bitCount < 64: * temp8byte &= mask # <<<<<<<<<<<<<< @@ -7643,7 +7510,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); - /* "dataRead.pyx":483 + /* "dataRead.pyx":470 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 64: # <<<<<<<<<<<<<< @@ -7652,7 +7519,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ } - /* "dataRead.pyx":485 + /* "dataRead.pyx":472 * if bitCount < 64: * temp8byte &= mask * buf[i] = temp8byte # <<<<<<<<<<<<<< @@ -7664,22 +7531,22 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ if (unlikely(__pyx_t_12 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 485, __pyx_L1_error) + __PYX_ERR(0, 472, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp8byte; } - /* "dataRead.pyx":476 + /* "dataRead.pyx":463 * return buf.byteswap() * elif nBytes == 8: * if swap == 0: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) */ - goto __pyx_L8; + goto __pyx_L7; } - /* "dataRead.pyx":487 + /* "dataRead.pyx":474 * buf[i] = temp8byte * else: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -7692,7 +7559,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":488 + /* "dataRead.pyx":475 * else: * for i in range(numberOfRecords): * memcpy(&temp8, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -7701,7 +7568,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ (void)(memcpy((&__pyx_v_temp8), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":490 + /* "dataRead.pyx":477 * memcpy(&temp8, &bita[posByteBeg + record_byte_size * i], nBytes) * temp8byte = temp8[0]<<56 | temp8[1]<<48 | temp8[2]<<40 | temp8[3]<<32 | \ * temp8[4]<<24 | temp8[5]<<16 | temp8[6]<<8 | temp8[7] # swap bytes # <<<<<<<<<<<<<< @@ -7710,7 +7577,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ __pyx_v_temp8byte = (((((((((__pyx_v_temp8[0]) << 56) | ((__pyx_v_temp8[1]) << 48)) | ((__pyx_v_temp8[2]) << 40)) | ((__pyx_v_temp8[3]) << 32)) | ((__pyx_v_temp8[4]) << 24)) | ((__pyx_v_temp8[5]) << 16)) | ((__pyx_v_temp8[6]) << 8)) | (__pyx_v_temp8[7])); - /* "dataRead.pyx":492 + /* "dataRead.pyx":479 * temp8[4]<<24 | temp8[5]<<16 | temp8[6]<<8 | temp8[7] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -7720,7 +7587,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":493 + /* "dataRead.pyx":480 * # right shift * if bitOffset > 0: * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< @@ -7729,7 +7596,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":492 + /* "dataRead.pyx":479 * temp8[4]<<24 | temp8[5]<<16 | temp8[6]<<8 | temp8[7] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -7738,7 +7605,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ } - /* "dataRead.pyx":495 + /* "dataRead.pyx":482 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 64: # <<<<<<<<<<<<<< @@ -7748,7 +7615,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_bitCount < 64) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":496 + /* "dataRead.pyx":483 * # mask left part * if bitCount < 64: * temp8byte &= mask # <<<<<<<<<<<<<< @@ -7757,7 +7624,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); - /* "dataRead.pyx":495 + /* "dataRead.pyx":482 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 64: # <<<<<<<<<<<<<< @@ -7766,7 +7633,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ } - /* "dataRead.pyx":497 + /* "dataRead.pyx":484 * if bitCount < 64: * temp8byte &= mask * buf[i] = temp8byte # <<<<<<<<<<<<<< @@ -7778,24 +7645,24 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ if (unlikely(__pyx_t_13 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 497, __pyx_L1_error) + __PYX_ERR(0, 484, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp8byte; } } - __pyx_L8:; + __pyx_L7:; - /* "dataRead.pyx":475 + /* "dataRead.pyx":462 * else: * return buf.byteswap() * elif nBytes == 8: # <<<<<<<<<<<<<< * if swap == 0: * for i in range(numberOfRecords): */ - goto __pyx_L4; + goto __pyx_L3; } - /* "dataRead.pyx":498 + /* "dataRead.pyx":485 * temp8byte &= mask * buf[i] = temp8byte * elif nBytes == 7: # <<<<<<<<<<<<<< @@ -7805,7 +7672,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_nBytes == 7) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":499 + /* "dataRead.pyx":486 * buf[i] = temp8byte * elif nBytes == 7: * if swap == 0: # <<<<<<<<<<<<<< @@ -7815,7 +7682,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":500 + /* "dataRead.pyx":487 * elif nBytes == 7: * if swap == 0: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -7827,7 +7694,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":501 + /* "dataRead.pyx":488 * if swap == 0: * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -7836,7 +7703,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":503 + /* "dataRead.pyx":490 * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -7846,7 +7713,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":504 + /* "dataRead.pyx":491 * # right shift * if bitOffset > 0: * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< @@ -7855,7 +7722,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":503 + /* "dataRead.pyx":490 * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -7864,7 +7731,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ } - /* "dataRead.pyx":506 + /* "dataRead.pyx":493 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 56: # <<<<<<<<<<<<<< @@ -7874,7 +7741,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_bitCount < 56) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":507 + /* "dataRead.pyx":494 * # mask left part * if bitCount < 56: * temp8byte &= mask # <<<<<<<<<<<<<< @@ -7883,7 +7750,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); - /* "dataRead.pyx":506 + /* "dataRead.pyx":493 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 56: # <<<<<<<<<<<<<< @@ -7892,7 +7759,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ } - /* "dataRead.pyx":508 + /* "dataRead.pyx":495 * if bitCount < 56: * temp8byte &= mask * buf[i] = temp8byte # <<<<<<<<<<<<<< @@ -7904,22 +7771,22 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ if (unlikely(__pyx_t_14 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 508, __pyx_L1_error) + __PYX_ERR(0, 495, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp8byte; } - /* "dataRead.pyx":499 + /* "dataRead.pyx":486 * buf[i] = temp8byte * elif nBytes == 7: * if swap == 0: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) */ - goto __pyx_L17; + goto __pyx_L16; } - /* "dataRead.pyx":510 + /* "dataRead.pyx":497 * buf[i] = temp8byte * else: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -7932,7 +7799,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":511 + /* "dataRead.pyx":498 * else: * for i in range(numberOfRecords): * memcpy(&temp7, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -7941,7 +7808,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ (void)(memcpy((&__pyx_v_temp7), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":513 + /* "dataRead.pyx":500 * memcpy(&temp7, &bita[posByteBeg + record_byte_size * i], nBytes) * temp8byte = temp7[0]<<48 | temp7[1]<<40 | temp7[2]<<32 | \ * temp7[3]<<24 | temp7[4]<<16 | temp7[5]<<8 | temp7[6] # swap bytes # <<<<<<<<<<<<<< @@ -7950,7 +7817,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ __pyx_v_temp8byte = ((((((((__pyx_v_temp7[0]) << 48) | ((__pyx_v_temp7[1]) << 40)) | ((__pyx_v_temp7[2]) << 32)) | ((__pyx_v_temp7[3]) << 24)) | ((__pyx_v_temp7[4]) << 16)) | ((__pyx_v_temp7[5]) << 8)) | (__pyx_v_temp7[6])); - /* "dataRead.pyx":515 + /* "dataRead.pyx":502 * temp7[3]<<24 | temp7[4]<<16 | temp7[5]<<8 | temp7[6] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -7960,7 +7827,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":516 + /* "dataRead.pyx":503 * # right shift * if bitOffset > 0: * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< @@ -7969,7 +7836,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":515 + /* "dataRead.pyx":502 * temp7[3]<<24 | temp7[4]<<16 | temp7[5]<<8 | temp7[6] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -7978,7 +7845,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ } - /* "dataRead.pyx":518 + /* "dataRead.pyx":505 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 56: # <<<<<<<<<<<<<< @@ -7988,7 +7855,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_bitCount < 56) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":519 + /* "dataRead.pyx":506 * # mask left part * if bitCount < 56: * temp8byte &= mask # <<<<<<<<<<<<<< @@ -7997,7 +7864,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); - /* "dataRead.pyx":518 + /* "dataRead.pyx":505 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 56: # <<<<<<<<<<<<<< @@ -8006,7 +7873,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ } - /* "dataRead.pyx":520 + /* "dataRead.pyx":507 * if bitCount < 56: * temp8byte &= mask * buf[i] = temp8byte # <<<<<<<<<<<<<< @@ -8018,24 +7885,24 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ if (unlikely(__pyx_t_15 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 520, __pyx_L1_error) + __PYX_ERR(0, 507, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_15, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp8byte; } } - __pyx_L17:; + __pyx_L16:; - /* "dataRead.pyx":498 + /* "dataRead.pyx":485 * temp8byte &= mask * buf[i] = temp8byte * elif nBytes == 7: # <<<<<<<<<<<<<< * if swap == 0: * for i in range(numberOfRecords): */ - goto __pyx_L4; + goto __pyx_L3; } - /* "dataRead.pyx":521 + /* "dataRead.pyx":508 * temp8byte &= mask * buf[i] = temp8byte * elif nBytes == 6: # <<<<<<<<<<<<<< @@ -8045,7 +7912,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_nBytes == 6) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":522 + /* "dataRead.pyx":509 * buf[i] = temp8byte * elif nBytes == 6: * if swap == 0: # <<<<<<<<<<<<<< @@ -8055,7 +7922,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":523 + /* "dataRead.pyx":510 * elif nBytes == 6: * if swap == 0: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -8067,7 +7934,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":524 + /* "dataRead.pyx":511 * if swap == 0: * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -8076,7 +7943,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":526 + /* "dataRead.pyx":513 * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -8086,7 +7953,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":527 + /* "dataRead.pyx":514 * # right shift * if bitOffset > 0: * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< @@ -8095,7 +7962,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":526 + /* "dataRead.pyx":513 * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -8104,7 +7971,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ } - /* "dataRead.pyx":529 + /* "dataRead.pyx":516 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 48: # <<<<<<<<<<<<<< @@ -8114,7 +7981,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_bitCount < 48) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":530 + /* "dataRead.pyx":517 * # mask left part * if bitCount < 48: * temp8byte &= mask # <<<<<<<<<<<<<< @@ -8123,7 +7990,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); - /* "dataRead.pyx":529 + /* "dataRead.pyx":516 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 48: # <<<<<<<<<<<<<< @@ -8132,7 +7999,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ } - /* "dataRead.pyx":531 + /* "dataRead.pyx":518 * if bitCount < 48: * temp8byte &= mask * buf[i] = temp8byte # <<<<<<<<<<<<<< @@ -8144,22 +8011,22 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ if (unlikely(__pyx_t_16 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 531, __pyx_L1_error) + __PYX_ERR(0, 518, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp8byte; } - /* "dataRead.pyx":522 + /* "dataRead.pyx":509 * buf[i] = temp8byte * elif nBytes == 6: * if swap == 0: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) */ - goto __pyx_L26; + goto __pyx_L25; } - /* "dataRead.pyx":533 + /* "dataRead.pyx":520 * buf[i] = temp8byte * else: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -8172,7 +8039,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":534 + /* "dataRead.pyx":521 * else: * for i in range(numberOfRecords): * memcpy(&temp6, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -8181,7 +8048,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ (void)(memcpy((&__pyx_v_temp6), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":536 + /* "dataRead.pyx":523 * memcpy(&temp6, &bita[posByteBeg + record_byte_size * i], nBytes) * temp8byte = temp6[0]<<40 | temp6[1]<<32 | temp6[2]<<24 | \ * temp6[3]<<16 | temp6[4]<<8 | temp6[5] # swap bytes # <<<<<<<<<<<<<< @@ -8190,7 +8057,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ __pyx_v_temp8byte = (((((((__pyx_v_temp6[0]) << 40) | ((__pyx_v_temp6[1]) << 32)) | ((__pyx_v_temp6[2]) << 24)) | ((__pyx_v_temp6[3]) << 16)) | ((__pyx_v_temp6[4]) << 8)) | (__pyx_v_temp6[5])); - /* "dataRead.pyx":538 + /* "dataRead.pyx":525 * temp6[3]<<16 | temp6[4]<<8 | temp6[5] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -8200,7 +8067,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":539 + /* "dataRead.pyx":526 * # right shift * if bitOffset > 0: * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< @@ -8209,7 +8076,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":538 + /* "dataRead.pyx":525 * temp6[3]<<16 | temp6[4]<<8 | temp6[5] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -8218,7 +8085,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ } - /* "dataRead.pyx":541 + /* "dataRead.pyx":528 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 48: # <<<<<<<<<<<<<< @@ -8228,7 +8095,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_bitCount < 48) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":542 + /* "dataRead.pyx":529 * # mask left part * if bitCount < 48: * temp8byte &= mask # <<<<<<<<<<<<<< @@ -8237,7 +8104,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); - /* "dataRead.pyx":541 + /* "dataRead.pyx":528 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 48: # <<<<<<<<<<<<<< @@ -8246,7 +8113,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ } - /* "dataRead.pyx":543 + /* "dataRead.pyx":530 * if bitCount < 48: * temp8byte &= mask * buf[i] = temp8byte # <<<<<<<<<<<<<< @@ -8258,24 +8125,24 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ if (unlikely(__pyx_t_17 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 543, __pyx_L1_error) + __PYX_ERR(0, 530, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_17, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp8byte; } } - __pyx_L26:; + __pyx_L25:; - /* "dataRead.pyx":521 + /* "dataRead.pyx":508 * temp8byte &= mask * buf[i] = temp8byte * elif nBytes == 6: # <<<<<<<<<<<<<< * if swap == 0: * for i in range(numberOfRecords): */ - goto __pyx_L4; + goto __pyx_L3; } - /* "dataRead.pyx":544 + /* "dataRead.pyx":531 * temp8byte &= mask * buf[i] = temp8byte * elif nBytes == 5: # <<<<<<<<<<<<<< @@ -8285,7 +8152,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_nBytes == 5) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":545 + /* "dataRead.pyx":532 * buf[i] = temp8byte * elif nBytes == 5: * if swap == 0: # <<<<<<<<<<<<<< @@ -8295,7 +8162,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":546 + /* "dataRead.pyx":533 * elif nBytes == 5: * if swap == 0: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -8307,7 +8174,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":547 + /* "dataRead.pyx":534 * if swap == 0: * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -8316,7 +8183,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":549 + /* "dataRead.pyx":536 * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -8326,7 +8193,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":550 + /* "dataRead.pyx":537 * # right shift * if bitOffset > 0: * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< @@ -8335,7 +8202,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":549 + /* "dataRead.pyx":536 * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -8344,7 +8211,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ } - /* "dataRead.pyx":552 + /* "dataRead.pyx":539 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 32: # <<<<<<<<<<<<<< @@ -8354,7 +8221,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_bitCount < 32) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":553 + /* "dataRead.pyx":540 * # mask left part * if bitCount < 32: * temp8byte &= mask # <<<<<<<<<<<<<< @@ -8363,7 +8230,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); - /* "dataRead.pyx":552 + /* "dataRead.pyx":539 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 32: # <<<<<<<<<<<<<< @@ -8372,7 +8239,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ } - /* "dataRead.pyx":554 + /* "dataRead.pyx":541 * if bitCount < 32: * temp8byte &= mask * buf[i] = temp8byte # <<<<<<<<<<<<<< @@ -8384,22 +8251,22 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ if (unlikely(__pyx_t_18 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 554, __pyx_L1_error) + __PYX_ERR(0, 541, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp8byte; } - /* "dataRead.pyx":545 + /* "dataRead.pyx":532 * buf[i] = temp8byte * elif nBytes == 5: * if swap == 0: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) */ - goto __pyx_L35; + goto __pyx_L34; } - /* "dataRead.pyx":556 + /* "dataRead.pyx":543 * buf[i] = temp8byte * else: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -8412,7 +8279,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":557 + /* "dataRead.pyx":544 * else: * for i in range(numberOfRecords): * memcpy(&temp5, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -8421,7 +8288,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ (void)(memcpy((&__pyx_v_temp5), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":559 + /* "dataRead.pyx":546 * memcpy(&temp5, &bita[posByteBeg + record_byte_size * i], nBytes) * temp8byte = temp5[0]<<32 | temp5[1]<<24 | \ * temp5[2]<<16 | temp5[3]<<8 | temp5[4] # swap bytes # <<<<<<<<<<<<<< @@ -8430,7 +8297,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ __pyx_v_temp8byte = ((((((__pyx_v_temp5[0]) << 32) | ((__pyx_v_temp5[1]) << 24)) | ((__pyx_v_temp5[2]) << 16)) | ((__pyx_v_temp5[3]) << 8)) | (__pyx_v_temp5[4])); - /* "dataRead.pyx":561 + /* "dataRead.pyx":548 * temp5[2]<<16 | temp5[3]<<8 | temp5[4] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -8440,7 +8307,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":562 + /* "dataRead.pyx":549 * # right shift * if bitOffset > 0: * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< @@ -8449,7 +8316,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":561 + /* "dataRead.pyx":548 * temp5[2]<<16 | temp5[3]<<8 | temp5[4] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -8458,7 +8325,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ } - /* "dataRead.pyx":564 + /* "dataRead.pyx":551 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 32: # <<<<<<<<<<<<<< @@ -8468,7 +8335,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_6 = ((__pyx_v_bitCount < 32) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":565 + /* "dataRead.pyx":552 * # mask left part * if bitCount < 32: * temp8byte &= mask # <<<<<<<<<<<<<< @@ -8477,7 +8344,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); - /* "dataRead.pyx":564 + /* "dataRead.pyx":551 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 32: # <<<<<<<<<<<<<< @@ -8486,7 +8353,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ */ } - /* "dataRead.pyx":566 + /* "dataRead.pyx":553 * if bitCount < 32: * temp8byte &= mask * buf[i] = temp8byte # <<<<<<<<<<<<<< @@ -8498,14 +8365,14 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ if (unlikely(__pyx_t_19 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 566, __pyx_L1_error) + __PYX_ERR(0, 553, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_uint64_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_19, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp8byte; } } - __pyx_L35:; + __pyx_L34:; - /* "dataRead.pyx":544 + /* "dataRead.pyx":531 * temp8byte &= mask * buf[i] = temp8byte * elif nBytes == 5: # <<<<<<<<<<<<<< @@ -8513,9 +8380,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ * for i in range(numberOfRecords): */ } - __pyx_L4:; + __pyx_L3:; - /* "dataRead.pyx":567 + /* "dataRead.pyx":554 * temp8byte &= mask * buf[i] = temp8byte * return buf # <<<<<<<<<<<<<< @@ -8527,12 +8394,12 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_r = ((PyObject *)__pyx_v_buf); goto __pyx_L0; - /* "dataRead.pyx":453 + /* "dataRead.pyx":443 * return buf * * cdef inline dataReadULongLong(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): + * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): */ /* function exit code */ @@ -8559,20 +8426,19 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ return __pyx_r; } -/* "dataRead.pyx":569 +/* "dataRead.pyx":556 * return buf * * cdef inline dataReadLongLong(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): + * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): */ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_bitCount, unsigned char __pyx_v_bitOffset, unsigned char __pyx_v_swap) { +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_bitCount, unsigned char __pyx_v_bitOffset, unsigned long __pyx_v_nBytes, unsigned char __pyx_v_swap) { PyArrayObject *__pyx_v_buf = 0; unsigned PY_LONG_LONG __pyx_v_i; PY_LONG_LONG __pyx_v_mask; PY_LONG_LONG __pyx_v_temp8byte; - unsigned char __pyx_v_nBytes; long __pyx_v_signBit; PY_LONG_LONG __pyx_v_signBitMask; PY_LONG_LONG __pyx_v_signExtend; @@ -8609,40 +8475,40 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_pybuffernd_buf.data = NULL; __pyx_pybuffernd_buf.rcbuffer = &__pyx_pybuffer_buf; - /* "dataRead.pyx":572 + /* "dataRead.pyx":559 * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): + * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): * cdef np.ndarray[np.int64_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array # <<<<<<<<<<<<<< * cdef unsigned long long i * cdef long long mask = ((1 << bitCount) - 1) */ - __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 572, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 559, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 572, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 559, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_numberOfRecords); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 572, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_numberOfRecords); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 559, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 572, __pyx_L1_error) + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 559, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 572, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 559, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 572, __pyx_L1_error) - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 572, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 559, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 559, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 572, __pyx_L1_error) + if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 559, __pyx_L1_error) __pyx_t_5 = ((PyArrayObject *)__pyx_t_4); { __Pyx_BufFmt_StackElem __pyx_stack[1]; if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_buf.rcbuffer->pybuffer, (PyObject*)__pyx_t_5, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) { __pyx_v_buf = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf = NULL; - __PYX_ERR(0, 572, __pyx_L1_error) + __PYX_ERR(0, 559, __pyx_L1_error) } else {__pyx_pybuffernd_buf.diminfo[0].strides = __pyx_pybuffernd_buf.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_buf.diminfo[0].shape = __pyx_pybuffernd_buf.rcbuffer->pybuffer.shape[0]; } } @@ -8650,44 +8516,35 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_v_buf = ((PyArrayObject *)__pyx_t_4); __pyx_t_4 = 0; - /* "dataRead.pyx":574 + /* "dataRead.pyx":561 * cdef np.ndarray[np.int64_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array * cdef unsigned long long i * cdef long long mask = ((1 << bitCount) - 1) # <<<<<<<<<<<<<< * cdef long long temp8byte = 0 - * cdef unsigned char nBytes = bitCount + bitOffset // 8 + * cdef long signBit = 0 */ __pyx_v_mask = ((1 << __pyx_v_bitCount) - 1); - /* "dataRead.pyx":575 + /* "dataRead.pyx":562 * cdef unsigned long long i * cdef long long mask = ((1 << bitCount) - 1) * cdef long long temp8byte = 0 # <<<<<<<<<<<<<< - * cdef unsigned char nBytes = bitCount + bitOffset // 8 * cdef long signBit = 0 + * cdef long long signBitMask = (1 << (bitCount-1)) */ __pyx_v_temp8byte = 0; - /* "dataRead.pyx":576 + /* "dataRead.pyx":563 * cdef long long mask = ((1 << bitCount) - 1) * cdef long long temp8byte = 0 - * cdef unsigned char nBytes = bitCount + bitOffset // 8 # <<<<<<<<<<<<<< - * cdef long signBit = 0 - * cdef long long signBitMask = (1 << (bitCount-1)) - */ - __pyx_v_nBytes = (__pyx_v_bitCount + __Pyx_div_long(__pyx_v_bitOffset, 8)); - - /* "dataRead.pyx":577 - * cdef long long temp8byte = 0 - * cdef unsigned char nBytes = bitCount + bitOffset // 8 * cdef long signBit = 0 # <<<<<<<<<<<<<< * cdef long long signBitMask = (1 << (bitCount-1)) * cdef long long signExtend = ((1 << (64 - bitCount)) - 1) << bitCount */ __pyx_v_signBit = 0; - /* "dataRead.pyx":578 - * cdef unsigned char nBytes = bitCount + bitOffset // 8 + /* "dataRead.pyx":564 + * cdef long long temp8byte = 0 * cdef long signBit = 0 * cdef long long signBitMask = (1 << (bitCount-1)) # <<<<<<<<<<<<<< * cdef long long signExtend = ((1 << (64 - bitCount)) - 1) << bitCount @@ -8695,7 +8552,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_signBitMask = (1 << (__pyx_v_bitCount - 1)); - /* "dataRead.pyx":579 + /* "dataRead.pyx":565 * cdef long signBit = 0 * cdef long long signBitMask = (1 << (bitCount-1)) * cdef long long signExtend = ((1 << (64 - bitCount)) - 1) << bitCount # <<<<<<<<<<<<<< @@ -8704,37 +8561,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_signExtend = (((1 << (64 - __pyx_v_bitCount)) - 1) << __pyx_v_bitCount); - /* "dataRead.pyx":584 - * cdef char temp6[6] - * cdef char temp5[5] - * if bitCount + bitOffset % 8 > 0: # <<<<<<<<<<<<<< - * nBytes += 1 - * if bitCount == 64: - */ - __pyx_t_6 = (((__pyx_v_bitCount + __Pyx_mod_long(__pyx_v_bitOffset, 8)) > 0) != 0); - if (__pyx_t_6) { - - /* "dataRead.pyx":585 - * cdef char temp5[5] - * if bitCount + bitOffset % 8 > 0: - * nBytes += 1 # <<<<<<<<<<<<<< - * if bitCount == 64: - * for i in range(numberOfRecords): - */ - __pyx_v_nBytes = (__pyx_v_nBytes + 1); - - /* "dataRead.pyx":584 + /* "dataRead.pyx":570 * cdef char temp6[6] * cdef char temp5[5] - * if bitCount + bitOffset % 8 > 0: # <<<<<<<<<<<<<< - * nBytes += 1 - * if bitCount == 64: - */ - } - - /* "dataRead.pyx":586 - * if bitCount + bitOffset % 8 > 0: - * nBytes += 1 * if bitCount == 64: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) @@ -8742,8 +8571,8 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_bitCount == 64) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":587 - * nBytes += 1 + /* "dataRead.pyx":571 + * cdef char temp5[5] * if bitCount == 64: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) @@ -8754,7 +8583,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":588 + /* "dataRead.pyx":572 * if bitCount == 64: * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -8763,7 +8592,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":589 + /* "dataRead.pyx":573 * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) * buf[i] = temp8byte # <<<<<<<<<<<<<< @@ -8775,12 +8604,12 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ if (unlikely(__pyx_t_10 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 589, __pyx_L1_error) + __PYX_ERR(0, 573, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp8byte; } - /* "dataRead.pyx":590 + /* "dataRead.pyx":574 * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) * buf[i] = temp8byte * if swap == 0: # <<<<<<<<<<<<<< @@ -8790,7 +8619,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":591 + /* "dataRead.pyx":575 * buf[i] = temp8byte * if swap == 0: * return buf # <<<<<<<<<<<<<< @@ -8802,7 +8631,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_r = ((PyObject *)__pyx_v_buf); goto __pyx_L0; - /* "dataRead.pyx":590 + /* "dataRead.pyx":574 * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) * buf[i] = temp8byte * if swap == 0: # <<<<<<<<<<<<<< @@ -8811,7 +8640,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":593 + /* "dataRead.pyx":577 * return buf * else: * return buf.byteswap() # <<<<<<<<<<<<<< @@ -8820,7 +8649,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ /*else*/ { __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_buf), __pyx_n_s_byteswap); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 593, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_buf), __pyx_n_s_byteswap); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 577, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) { @@ -8833,10 +8662,10 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ } } if (__pyx_t_3) { - __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 593, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 577, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; } else { - __pyx_t_4 = __Pyx_PyObject_CallNoArg(__pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 593, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_CallNoArg(__pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 577, __pyx_L1_error) } __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; @@ -8845,16 +8674,16 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ goto __pyx_L0; } - /* "dataRead.pyx":586 - * if bitCount + bitOffset % 8 > 0: - * nBytes += 1 + /* "dataRead.pyx":570 + * cdef char temp6[6] + * cdef char temp5[5] * if bitCount == 64: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) */ } - /* "dataRead.pyx":594 + /* "dataRead.pyx":578 * else: * return buf.byteswap() * elif nBytes == 8: # <<<<<<<<<<<<<< @@ -8864,7 +8693,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_nBytes == 8) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":595 + /* "dataRead.pyx":579 * return buf.byteswap() * elif nBytes == 8: * if swap == 0: # <<<<<<<<<<<<<< @@ -8874,7 +8703,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":596 + /* "dataRead.pyx":580 * elif nBytes == 8: * if swap == 0: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -8886,7 +8715,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":597 + /* "dataRead.pyx":581 * if swap == 0: * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -8895,7 +8724,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":599 + /* "dataRead.pyx":583 * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -8905,7 +8734,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":600 + /* "dataRead.pyx":584 * # right shift * if bitOffset > 0: * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< @@ -8914,7 +8743,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":599 + /* "dataRead.pyx":583 * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -8923,7 +8752,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":602 + /* "dataRead.pyx":586 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 64: # <<<<<<<<<<<<<< @@ -8933,7 +8762,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_bitCount < 64) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":603 + /* "dataRead.pyx":587 * # mask left part * if bitCount < 64: * temp8byte &= mask # <<<<<<<<<<<<<< @@ -8942,7 +8771,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); - /* "dataRead.pyx":602 + /* "dataRead.pyx":586 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 64: # <<<<<<<<<<<<<< @@ -8951,7 +8780,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":604 + /* "dataRead.pyx":588 * if bitCount < 64: * temp8byte &= mask * signBit = temp8byte & signBitMask # <<<<<<<<<<<<<< @@ -8960,7 +8789,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_signBit = (__pyx_v_temp8byte & __pyx_v_signBitMask); - /* "dataRead.pyx":605 + /* "dataRead.pyx":589 * temp8byte &= mask * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -8970,7 +8799,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = (__pyx_v_signBit != 0); if (__pyx_t_6) { - /* "dataRead.pyx":606 + /* "dataRead.pyx":590 * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend * temp8byte |= signExtend # <<<<<<<<<<<<<< @@ -8979,7 +8808,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_signExtend); - /* "dataRead.pyx":605 + /* "dataRead.pyx":589 * temp8byte &= mask * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -8988,7 +8817,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":607 + /* "dataRead.pyx":591 * if signBit: # negative value, sign extend * temp8byte |= signExtend * buf[i] = temp8byte # <<<<<<<<<<<<<< @@ -9000,22 +8829,22 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ if (unlikely(__pyx_t_12 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 607, __pyx_L1_error) + __PYX_ERR(0, 591, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp8byte; } - /* "dataRead.pyx":595 + /* "dataRead.pyx":579 * return buf.byteswap() * elif nBytes == 8: * if swap == 0: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) */ - goto __pyx_L8; + goto __pyx_L7; } - /* "dataRead.pyx":609 + /* "dataRead.pyx":593 * buf[i] = temp8byte * else: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -9028,7 +8857,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":610 + /* "dataRead.pyx":594 * else: * for i in range(numberOfRecords): * memcpy(&temp8, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -9037,7 +8866,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ (void)(memcpy((&__pyx_v_temp8), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":612 + /* "dataRead.pyx":596 * memcpy(&temp8, &bita[posByteBeg + record_byte_size * i], nBytes) * temp8byte = temp8[0]<<56 | temp8[1]<<48 | temp8[2]<<40 | temp8[3]<<32 | \ * temp8[4]<<24 | temp8[5]<<16 | temp8[6]<<8 | temp8[7] # swap bytes # <<<<<<<<<<<<<< @@ -9046,7 +8875,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (((((((((__pyx_v_temp8[0]) << 56) | ((__pyx_v_temp8[1]) << 48)) | ((__pyx_v_temp8[2]) << 40)) | ((__pyx_v_temp8[3]) << 32)) | ((__pyx_v_temp8[4]) << 24)) | ((__pyx_v_temp8[5]) << 16)) | ((__pyx_v_temp8[6]) << 8)) | (__pyx_v_temp8[7])); - /* "dataRead.pyx":614 + /* "dataRead.pyx":598 * temp8[4]<<24 | temp8[5]<<16 | temp8[6]<<8 | temp8[7] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -9056,7 +8885,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":615 + /* "dataRead.pyx":599 * # right shift * if bitOffset > 0: * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< @@ -9065,7 +8894,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":614 + /* "dataRead.pyx":598 * temp8[4]<<24 | temp8[5]<<16 | temp8[6]<<8 | temp8[7] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -9074,7 +8903,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":617 + /* "dataRead.pyx":601 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 64: # <<<<<<<<<<<<<< @@ -9084,7 +8913,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_bitCount < 64) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":618 + /* "dataRead.pyx":602 * # mask left part * if bitCount < 64: * temp8byte &= mask # <<<<<<<<<<<<<< @@ -9093,7 +8922,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); - /* "dataRead.pyx":617 + /* "dataRead.pyx":601 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 64: # <<<<<<<<<<<<<< @@ -9102,7 +8931,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":619 + /* "dataRead.pyx":603 * if bitCount < 64: * temp8byte &= mask * signBit = temp8byte & signBitMask # <<<<<<<<<<<<<< @@ -9111,7 +8940,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_signBit = (__pyx_v_temp8byte & __pyx_v_signBitMask); - /* "dataRead.pyx":620 + /* "dataRead.pyx":604 * temp8byte &= mask * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -9121,7 +8950,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = (__pyx_v_signBit != 0); if (__pyx_t_6) { - /* "dataRead.pyx":621 + /* "dataRead.pyx":605 * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend * temp8byte |= signExtend # <<<<<<<<<<<<<< @@ -9130,7 +8959,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_signExtend); - /* "dataRead.pyx":620 + /* "dataRead.pyx":604 * temp8byte &= mask * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -9139,7 +8968,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":622 + /* "dataRead.pyx":606 * if signBit: # negative value, sign extend * temp8byte |= signExtend * buf[i] = temp8byte # <<<<<<<<<<<<<< @@ -9151,24 +8980,24 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ if (unlikely(__pyx_t_13 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 622, __pyx_L1_error) + __PYX_ERR(0, 606, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_13, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp8byte; } } - __pyx_L8:; + __pyx_L7:; - /* "dataRead.pyx":594 + /* "dataRead.pyx":578 * else: * return buf.byteswap() * elif nBytes == 8: # <<<<<<<<<<<<<< * if swap == 0: * for i in range(numberOfRecords): */ - goto __pyx_L4; + goto __pyx_L3; } - /* "dataRead.pyx":623 + /* "dataRead.pyx":607 * temp8byte |= signExtend * buf[i] = temp8byte * elif nBytes == 7: # <<<<<<<<<<<<<< @@ -9178,7 +9007,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_nBytes == 7) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":624 + /* "dataRead.pyx":608 * buf[i] = temp8byte * elif nBytes == 7: * if swap == 0: # <<<<<<<<<<<<<< @@ -9188,7 +9017,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":625 + /* "dataRead.pyx":609 * elif nBytes == 7: * if swap == 0: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -9200,7 +9029,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":626 + /* "dataRead.pyx":610 * if swap == 0: * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -9209,7 +9038,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":628 + /* "dataRead.pyx":612 * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -9219,7 +9048,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":629 + /* "dataRead.pyx":613 * # right shift * if bitOffset > 0: * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< @@ -9228,7 +9057,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":628 + /* "dataRead.pyx":612 * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -9237,7 +9066,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":631 + /* "dataRead.pyx":615 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 56: # <<<<<<<<<<<<<< @@ -9247,7 +9076,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_bitCount < 56) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":632 + /* "dataRead.pyx":616 * # mask left part * if bitCount < 56: * temp8byte &= mask # <<<<<<<<<<<<<< @@ -9256,7 +9085,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); - /* "dataRead.pyx":631 + /* "dataRead.pyx":615 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 56: # <<<<<<<<<<<<<< @@ -9265,7 +9094,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":633 + /* "dataRead.pyx":617 * if bitCount < 56: * temp8byte &= mask * signBit = temp8byte & signBitMask # <<<<<<<<<<<<<< @@ -9274,7 +9103,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_signBit = (__pyx_v_temp8byte & __pyx_v_signBitMask); - /* "dataRead.pyx":634 + /* "dataRead.pyx":618 * temp8byte &= mask * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -9284,7 +9113,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = (__pyx_v_signBit != 0); if (__pyx_t_6) { - /* "dataRead.pyx":635 + /* "dataRead.pyx":619 * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend * temp8byte |= signExtend # <<<<<<<<<<<<<< @@ -9293,7 +9122,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_signExtend); - /* "dataRead.pyx":634 + /* "dataRead.pyx":618 * temp8byte &= mask * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -9302,7 +9131,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":636 + /* "dataRead.pyx":620 * if signBit: # negative value, sign extend * temp8byte |= signExtend * buf[i] = temp8byte # <<<<<<<<<<<<<< @@ -9314,22 +9143,22 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ if (unlikely(__pyx_t_14 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 636, __pyx_L1_error) + __PYX_ERR(0, 620, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp8byte; } - /* "dataRead.pyx":624 + /* "dataRead.pyx":608 * buf[i] = temp8byte * elif nBytes == 7: * if swap == 0: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) */ - goto __pyx_L19; + goto __pyx_L18; } - /* "dataRead.pyx":638 + /* "dataRead.pyx":622 * buf[i] = temp8byte * else: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -9342,7 +9171,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":639 + /* "dataRead.pyx":623 * else: * for i in range(numberOfRecords): * memcpy(&temp7, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -9351,7 +9180,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ (void)(memcpy((&__pyx_v_temp7), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":641 + /* "dataRead.pyx":625 * memcpy(&temp7, &bita[posByteBeg + record_byte_size * i], nBytes) * temp8byte = temp7[0]<<48 | temp7[1]<<40 | temp7[2]<<32 | \ * temp7[3]<<24 | temp7[4]<<16 | temp7[5]<<8 | temp7[6] # swap bytes # <<<<<<<<<<<<<< @@ -9360,7 +9189,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = ((((((((__pyx_v_temp7[0]) << 48) | ((__pyx_v_temp7[1]) << 40)) | ((__pyx_v_temp7[2]) << 32)) | ((__pyx_v_temp7[3]) << 24)) | ((__pyx_v_temp7[4]) << 16)) | ((__pyx_v_temp7[5]) << 8)) | (__pyx_v_temp7[6])); - /* "dataRead.pyx":643 + /* "dataRead.pyx":627 * temp7[3]<<24 | temp7[4]<<16 | temp7[5]<<8 | temp7[6] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -9370,7 +9199,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":644 + /* "dataRead.pyx":628 * # right shift * if bitOffset > 0: * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< @@ -9379,7 +9208,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":643 + /* "dataRead.pyx":627 * temp7[3]<<24 | temp7[4]<<16 | temp7[5]<<8 | temp7[6] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -9388,7 +9217,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":646 + /* "dataRead.pyx":630 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 56: # <<<<<<<<<<<<<< @@ -9398,7 +9227,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_bitCount < 56) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":647 + /* "dataRead.pyx":631 * # mask left part * if bitCount < 56: * temp8byte &= mask # <<<<<<<<<<<<<< @@ -9407,7 +9236,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); - /* "dataRead.pyx":646 + /* "dataRead.pyx":630 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 56: # <<<<<<<<<<<<<< @@ -9416,7 +9245,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":648 + /* "dataRead.pyx":632 * if bitCount < 56: * temp8byte &= mask * signBit = temp8byte & signBitMask # <<<<<<<<<<<<<< @@ -9425,7 +9254,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_signBit = (__pyx_v_temp8byte & __pyx_v_signBitMask); - /* "dataRead.pyx":649 + /* "dataRead.pyx":633 * temp8byte &= mask * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -9435,7 +9264,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = (__pyx_v_signBit != 0); if (__pyx_t_6) { - /* "dataRead.pyx":650 + /* "dataRead.pyx":634 * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend * temp8byte |= signExtend # <<<<<<<<<<<<<< @@ -9444,7 +9273,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_signExtend); - /* "dataRead.pyx":649 + /* "dataRead.pyx":633 * temp8byte &= mask * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -9453,7 +9282,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":651 + /* "dataRead.pyx":635 * if signBit: # negative value, sign extend * temp8byte |= signExtend * buf[i] = temp8byte # <<<<<<<<<<<<<< @@ -9465,24 +9294,24 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ if (unlikely(__pyx_t_15 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 651, __pyx_L1_error) + __PYX_ERR(0, 635, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_15, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp8byte; } } - __pyx_L19:; + __pyx_L18:; - /* "dataRead.pyx":623 + /* "dataRead.pyx":607 * temp8byte |= signExtend * buf[i] = temp8byte * elif nBytes == 7: # <<<<<<<<<<<<<< * if swap == 0: * for i in range(numberOfRecords): */ - goto __pyx_L4; + goto __pyx_L3; } - /* "dataRead.pyx":652 + /* "dataRead.pyx":636 * temp8byte |= signExtend * buf[i] = temp8byte * elif nBytes == 6: # <<<<<<<<<<<<<< @@ -9492,7 +9321,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_nBytes == 6) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":653 + /* "dataRead.pyx":637 * buf[i] = temp8byte * elif nBytes == 6: * if swap == 0: # <<<<<<<<<<<<<< @@ -9502,7 +9331,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":654 + /* "dataRead.pyx":638 * elif nBytes == 6: * if swap == 0: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -9514,7 +9343,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":655 + /* "dataRead.pyx":639 * if swap == 0: * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -9523,7 +9352,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":657 + /* "dataRead.pyx":641 * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -9533,7 +9362,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":658 + /* "dataRead.pyx":642 * # right shift * if bitOffset > 0: * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< @@ -9542,7 +9371,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":657 + /* "dataRead.pyx":641 * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -9551,7 +9380,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":660 + /* "dataRead.pyx":644 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 48: # <<<<<<<<<<<<<< @@ -9561,7 +9390,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_bitCount < 48) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":661 + /* "dataRead.pyx":645 * # mask left part * if bitCount < 48: * temp8byte &= mask # <<<<<<<<<<<<<< @@ -9570,7 +9399,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); - /* "dataRead.pyx":660 + /* "dataRead.pyx":644 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 48: # <<<<<<<<<<<<<< @@ -9579,7 +9408,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":662 + /* "dataRead.pyx":646 * if bitCount < 48: * temp8byte &= mask * signBit = temp8byte & signBitMask # <<<<<<<<<<<<<< @@ -9588,7 +9417,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_signBit = (__pyx_v_temp8byte & __pyx_v_signBitMask); - /* "dataRead.pyx":663 + /* "dataRead.pyx":647 * temp8byte &= mask * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -9598,7 +9427,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = (__pyx_v_signBit != 0); if (__pyx_t_6) { - /* "dataRead.pyx":664 + /* "dataRead.pyx":648 * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend * temp8byte |= signExtend # <<<<<<<<<<<<<< @@ -9607,7 +9436,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_signExtend); - /* "dataRead.pyx":663 + /* "dataRead.pyx":647 * temp8byte &= mask * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -9616,7 +9445,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":665 + /* "dataRead.pyx":649 * if signBit: # negative value, sign extend * temp8byte |= signExtend * buf[i] = temp8byte # <<<<<<<<<<<<<< @@ -9628,22 +9457,22 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ if (unlikely(__pyx_t_16 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 665, __pyx_L1_error) + __PYX_ERR(0, 649, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp8byte; } - /* "dataRead.pyx":653 + /* "dataRead.pyx":637 * buf[i] = temp8byte * elif nBytes == 6: * if swap == 0: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) */ - goto __pyx_L30; + goto __pyx_L29; } - /* "dataRead.pyx":667 + /* "dataRead.pyx":651 * buf[i] = temp8byte * else: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -9656,7 +9485,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":668 + /* "dataRead.pyx":652 * else: * for i in range(numberOfRecords): * memcpy(&temp6, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -9665,7 +9494,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ (void)(memcpy((&__pyx_v_temp6), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":670 + /* "dataRead.pyx":654 * memcpy(&temp6, &bita[posByteBeg + record_byte_size * i], nBytes) * temp8byte = temp6[0]<<40 | temp6[1]<<32 | temp6[2]<<24 | \ * temp6[3]<<16 | temp6[4]<<8 | temp6[5] # swap bytes # <<<<<<<<<<<<<< @@ -9674,7 +9503,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (((((((__pyx_v_temp6[0]) << 40) | ((__pyx_v_temp6[1]) << 32)) | ((__pyx_v_temp6[2]) << 24)) | ((__pyx_v_temp6[3]) << 16)) | ((__pyx_v_temp6[4]) << 8)) | (__pyx_v_temp6[5])); - /* "dataRead.pyx":672 + /* "dataRead.pyx":656 * temp6[3]<<16 | temp6[4]<<8 | temp6[5] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -9684,7 +9513,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":673 + /* "dataRead.pyx":657 * # right shift * if bitOffset > 0: * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< @@ -9693,7 +9522,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":672 + /* "dataRead.pyx":656 * temp6[3]<<16 | temp6[4]<<8 | temp6[5] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -9702,7 +9531,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":675 + /* "dataRead.pyx":659 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 48: # <<<<<<<<<<<<<< @@ -9712,7 +9541,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_bitCount < 48) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":676 + /* "dataRead.pyx":660 * # mask left part * if bitCount < 48: * temp8byte &= mask # <<<<<<<<<<<<<< @@ -9721,7 +9550,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); - /* "dataRead.pyx":675 + /* "dataRead.pyx":659 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 48: # <<<<<<<<<<<<<< @@ -9730,7 +9559,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":677 + /* "dataRead.pyx":661 * if bitCount < 48: * temp8byte &= mask * signBit = temp8byte & signBitMask # <<<<<<<<<<<<<< @@ -9739,7 +9568,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_signBit = (__pyx_v_temp8byte & __pyx_v_signBitMask); - /* "dataRead.pyx":678 + /* "dataRead.pyx":662 * temp8byte &= mask * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -9749,7 +9578,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = (__pyx_v_signBit != 0); if (__pyx_t_6) { - /* "dataRead.pyx":679 + /* "dataRead.pyx":663 * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend * temp8byte |= signExtend # <<<<<<<<<<<<<< @@ -9758,7 +9587,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_signExtend); - /* "dataRead.pyx":678 + /* "dataRead.pyx":662 * temp8byte &= mask * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -9767,7 +9596,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":680 + /* "dataRead.pyx":664 * if signBit: # negative value, sign extend * temp8byte |= signExtend * buf[i] = temp8byte # <<<<<<<<<<<<<< @@ -9779,24 +9608,24 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ if (unlikely(__pyx_t_17 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 680, __pyx_L1_error) + __PYX_ERR(0, 664, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_17, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp8byte; } } - __pyx_L30:; + __pyx_L29:; - /* "dataRead.pyx":652 + /* "dataRead.pyx":636 * temp8byte |= signExtend * buf[i] = temp8byte * elif nBytes == 6: # <<<<<<<<<<<<<< * if swap == 0: * for i in range(numberOfRecords): */ - goto __pyx_L4; + goto __pyx_L3; } - /* "dataRead.pyx":681 + /* "dataRead.pyx":665 * temp8byte |= signExtend * buf[i] = temp8byte * elif nBytes == 5: # <<<<<<<<<<<<<< @@ -9806,7 +9635,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_nBytes == 5) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":682 + /* "dataRead.pyx":666 * buf[i] = temp8byte * elif nBytes == 5: * if swap == 0: # <<<<<<<<<<<<<< @@ -9816,7 +9645,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":683 + /* "dataRead.pyx":667 * elif nBytes == 5: * if swap == 0: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -9828,7 +9657,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":684 + /* "dataRead.pyx":668 * if swap == 0: * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -9837,7 +9666,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":686 + /* "dataRead.pyx":670 * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -9847,7 +9676,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":687 + /* "dataRead.pyx":671 * # right shift * if bitOffset > 0: * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< @@ -9856,7 +9685,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":686 + /* "dataRead.pyx":670 * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -9865,7 +9694,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":689 + /* "dataRead.pyx":673 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 40: # <<<<<<<<<<<<<< @@ -9875,7 +9704,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_bitCount < 40) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":690 + /* "dataRead.pyx":674 * # mask left part * if bitCount < 40: * temp8byte &= mask # <<<<<<<<<<<<<< @@ -9884,7 +9713,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); - /* "dataRead.pyx":689 + /* "dataRead.pyx":673 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 40: # <<<<<<<<<<<<<< @@ -9893,7 +9722,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":691 + /* "dataRead.pyx":675 * if bitCount < 40: * temp8byte &= mask * signBit = temp8byte & signBitMask # <<<<<<<<<<<<<< @@ -9902,7 +9731,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_signBit = (__pyx_v_temp8byte & __pyx_v_signBitMask); - /* "dataRead.pyx":692 + /* "dataRead.pyx":676 * temp8byte &= mask * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -9912,7 +9741,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = (__pyx_v_signBit != 0); if (__pyx_t_6) { - /* "dataRead.pyx":693 + /* "dataRead.pyx":677 * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend * temp8byte |= signExtend # <<<<<<<<<<<<<< @@ -9921,7 +9750,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_signExtend); - /* "dataRead.pyx":692 + /* "dataRead.pyx":676 * temp8byte &= mask * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -9930,7 +9759,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":694 + /* "dataRead.pyx":678 * if signBit: # negative value, sign extend * temp8byte |= signExtend * buf[i] = temp8byte # <<<<<<<<<<<<<< @@ -9942,22 +9771,22 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ if (unlikely(__pyx_t_18 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 694, __pyx_L1_error) + __PYX_ERR(0, 678, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp8byte; } - /* "dataRead.pyx":682 + /* "dataRead.pyx":666 * buf[i] = temp8byte * elif nBytes == 5: * if swap == 0: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) */ - goto __pyx_L41; + goto __pyx_L40; } - /* "dataRead.pyx":696 + /* "dataRead.pyx":680 * buf[i] = temp8byte * else: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< @@ -9970,7 +9799,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; - /* "dataRead.pyx":697 + /* "dataRead.pyx":681 * else: * for i in range(numberOfRecords): * memcpy(&temp5, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< @@ -9979,7 +9808,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ (void)(memcpy((&__pyx_v_temp5), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); - /* "dataRead.pyx":699 + /* "dataRead.pyx":683 * memcpy(&temp5, &bita[posByteBeg + record_byte_size * i], nBytes) * temp8byte = temp5[0]<<32 | temp5[1]<<24 | \ * temp5[2]<<16 | temp5[3]<<8 | temp5[4] # swap bytes # <<<<<<<<<<<<<< @@ -9988,7 +9817,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = ((((((__pyx_v_temp5[0]) << 32) | ((__pyx_v_temp5[1]) << 24)) | ((__pyx_v_temp5[2]) << 16)) | ((__pyx_v_temp5[3]) << 8)) | (__pyx_v_temp5[4])); - /* "dataRead.pyx":701 + /* "dataRead.pyx":685 * temp5[2]<<16 | temp5[3]<<8 | temp5[4] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -9998,7 +9827,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":702 + /* "dataRead.pyx":686 * # right shift * if bitOffset > 0: * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< @@ -10007,7 +9836,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); - /* "dataRead.pyx":701 + /* "dataRead.pyx":685 * temp5[2]<<16 | temp5[3]<<8 | temp5[4] # swap bytes * # right shift * if bitOffset > 0: # <<<<<<<<<<<<<< @@ -10016,7 +9845,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":704 + /* "dataRead.pyx":688 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 40: # <<<<<<<<<<<<<< @@ -10026,7 +9855,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = ((__pyx_v_bitCount < 40) != 0); if (__pyx_t_6) { - /* "dataRead.pyx":705 + /* "dataRead.pyx":689 * # mask left part * if bitCount < 40: * temp8byte &= mask # <<<<<<<<<<<<<< @@ -10035,7 +9864,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); - /* "dataRead.pyx":704 + /* "dataRead.pyx":688 * temp8byte = temp8byte >> bitOffset * # mask left part * if bitCount < 40: # <<<<<<<<<<<<<< @@ -10044,7 +9873,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":706 + /* "dataRead.pyx":690 * if bitCount < 40: * temp8byte &= mask * signBit = temp8byte & signBitMask # <<<<<<<<<<<<<< @@ -10053,7 +9882,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_signBit = (__pyx_v_temp8byte & __pyx_v_signBitMask); - /* "dataRead.pyx":707 + /* "dataRead.pyx":691 * temp8byte &= mask * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -10063,7 +9892,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_6 = (__pyx_v_signBit != 0); if (__pyx_t_6) { - /* "dataRead.pyx":708 + /* "dataRead.pyx":692 * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend * temp8byte |= signExtend # <<<<<<<<<<<<<< @@ -10072,7 +9901,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_signExtend); - /* "dataRead.pyx":707 + /* "dataRead.pyx":691 * temp8byte &= mask * signBit = temp8byte & signBitMask * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< @@ -10081,7 +9910,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ */ } - /* "dataRead.pyx":709 + /* "dataRead.pyx":693 * if signBit: # negative value, sign extend * temp8byte |= signExtend * buf[i] = temp8byte # <<<<<<<<<<<<<< @@ -10093,14 +9922,14 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ if (unlikely(__pyx_t_19 >= (size_t)__pyx_pybuffernd_buf.diminfo[0].shape)) __pyx_t_11 = 0; if (unlikely(__pyx_t_11 != -1)) { __Pyx_RaiseBufferIndexError(__pyx_t_11); - __PYX_ERR(0, 709, __pyx_L1_error) + __PYX_ERR(0, 693, __pyx_L1_error) } *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int64_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_19, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp8byte; } } - __pyx_L41:; + __pyx_L40:; - /* "dataRead.pyx":681 + /* "dataRead.pyx":665 * temp8byte |= signExtend * buf[i] = temp8byte * elif nBytes == 5: # <<<<<<<<<<<<<< @@ -10108,9 +9937,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ * for i in range(numberOfRecords): */ } - __pyx_L4:; + __pyx_L3:; - /* "dataRead.pyx":710 + /* "dataRead.pyx":694 * temp8byte |= signExtend * buf[i] = temp8byte * return buf # <<<<<<<<<<<<<< @@ -10122,12 +9951,12 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_r = ((PyObject *)__pyx_v_buf); goto __pyx_L0; - /* "dataRead.pyx":569 + /* "dataRead.pyx":556 * return buf * * cdef inline dataReadLongLong(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): + * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): */ /* function exit code */ @@ -10154,17 +9983,18 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ return __pyx_r; } -/* "dataRead.pyx":712 +/* "dataRead.pyx":696 * return buf * * cdef inline dataReadByte(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, unsigned long posByteEnd, + * unsigned long record_byte_size, unsigned long posByteBeg, unsigned long nBytes, * unsigned long bitCount, unsigned char bitOffset): */ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadByte(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_posByteEnd, CYTHON_UNUSED unsigned long __pyx_v_bitCount, CYTHON_UNUSED unsigned char __pyx_v_bitOffset) { +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadByte(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_nBytes, CYTHON_UNUSED unsigned long __pyx_v_bitCount, CYTHON_UNUSED unsigned char __pyx_v_bitOffset) { PyArrayObject *__pyx_v_buf = 0; unsigned PY_LONG_LONG __pyx_v_i; + unsigned long __pyx_v_posByteEnd; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; @@ -10176,40 +10006,49 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadByte(char const *__pyx_ unsigned PY_LONG_LONG __pyx_t_7; __Pyx_RefNannySetupContext("dataReadByte", 0); - /* "dataRead.pyx":715 - * unsigned long record_byte_size, unsigned long posByteBeg, unsigned long posByteEnd, + /* "dataRead.pyx":699 + * unsigned long record_byte_size, unsigned long posByteBeg, unsigned long nBytes, * unsigned long bitCount, unsigned char bitOffset): * cdef np.ndarray buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array # <<<<<<<<<<<<<< * cdef unsigned long long i - * for i in range(numberOfRecords): + * cdef unsigned long posByteEnd = posByteBeg + nBytes */ - __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 715, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 699, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 715, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 699, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_numberOfRecords); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 715, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_numberOfRecords); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 699, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 715, __pyx_L1_error) + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 699, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 715, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 699, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 715, __pyx_L1_error) - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 715, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 699, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 699, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 715, __pyx_L1_error) + if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 699, __pyx_L1_error) __pyx_v_buf = ((PyArrayObject *)__pyx_t_4); __pyx_t_4 = 0; - /* "dataRead.pyx":717 + /* "dataRead.pyx":701 * cdef np.ndarray buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array * cdef unsigned long long i + * cdef unsigned long posByteEnd = posByteBeg + nBytes # <<<<<<<<<<<<<< + * for i in range(numberOfRecords): + * buf[i] = bytes(bita[posByteBeg + record_byte_size * i:\ + */ + __pyx_v_posByteEnd = (__pyx_v_posByteBeg + __pyx_v_nBytes); + + /* "dataRead.pyx":702 + * cdef unsigned long long i + * cdef unsigned long posByteEnd = posByteBeg + nBytes * for i in range(numberOfRecords): # <<<<<<<<<<<<<< * buf[i] = bytes(bita[posByteBeg + record_byte_size * i:\ * posByteEnd + record_byte_size * i]) @@ -10219,23 +10058,23 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadByte(char const *__pyx_ for (__pyx_t_7 = 0; __pyx_t_7 < __pyx_t_6; __pyx_t_7+=1) { __pyx_v_i = __pyx_t_7; - /* "dataRead.pyx":718 - * cdef unsigned long long i + /* "dataRead.pyx":703 + * cdef unsigned long posByteEnd = posByteBeg + nBytes * for i in range(numberOfRecords): * buf[i] = bytes(bita[posByteBeg + record_byte_size * i:\ # <<<<<<<<<<<<<< * posByteEnd + record_byte_size * i]) * return buf */ - __pyx_t_4 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_bita + (__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i)), (__pyx_v_posByteEnd + (__pyx_v_record_byte_size * __pyx_v_i)) - (__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 718, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_bita + (__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i)), (__pyx_v_posByteEnd + (__pyx_v_record_byte_size * __pyx_v_i)) - (__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 703, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - __pyx_t_1 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyBytes_Type)), __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 718, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyBytes_Type)), __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 703, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(__Pyx_SetItemInt(((PyObject *)__pyx_v_buf), __pyx_v_i, __pyx_t_1, unsigned PY_LONG_LONG, 0, __Pyx_PyInt_From_unsigned_PY_LONG_LONG, 0, 0, 1) < 0)) __PYX_ERR(0, 718, __pyx_L1_error) + if (unlikely(__Pyx_SetItemInt(((PyObject *)__pyx_v_buf), __pyx_v_i, __pyx_t_1, unsigned PY_LONG_LONG, 0, __Pyx_PyInt_From_unsigned_PY_LONG_LONG, 0, 0, 1) < 0)) __PYX_ERR(0, 703, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; } - /* "dataRead.pyx":720 + /* "dataRead.pyx":705 * buf[i] = bytes(bita[posByteBeg + record_byte_size * i:\ * posByteEnd + record_byte_size * i]) * return buf # <<<<<<<<<<<<<< @@ -10247,11 +10086,11 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadByte(char const *__pyx_ __pyx_r = ((PyObject *)__pyx_v_buf); goto __pyx_L0; - /* "dataRead.pyx":712 + /* "dataRead.pyx":696 * return buf * * cdef inline dataReadByte(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, unsigned long posByteEnd, + * unsigned long record_byte_size, unsigned long posByteBeg, unsigned long nBytes, * unsigned long bitCount, unsigned char bitOffset): */ @@ -10270,17 +10109,18 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadByte(char const *__pyx_ return __pyx_r; } -/* "dataRead.pyx":722 +/* "dataRead.pyx":707 * return buf * * cdef inline dataReadArray(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, unsigned long posByteEnd, + * unsigned long record_byte_size, unsigned long posByteBeg, unsigned long nBytes, * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): */ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_posByteEnd, CYTHON_UNUSED unsigned long __pyx_v_bitCount, CYTHON_UNUSED unsigned char __pyx_v_bitOffset, unsigned char __pyx_v_swap) { +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_nBytes, CYTHON_UNUSED unsigned long __pyx_v_bitCount, CYTHON_UNUSED unsigned char __pyx_v_bitOffset, unsigned char __pyx_v_swap) { PyArrayObject *__pyx_v_buf = 0; unsigned PY_LONG_LONG __pyx_v_i; + unsigned long __pyx_v_posByteEnd; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; @@ -10293,40 +10133,49 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *__pyx int __pyx_t_8; __Pyx_RefNannySetupContext("dataReadArray", 0); - /* "dataRead.pyx":725 - * unsigned long record_byte_size, unsigned long posByteBeg, unsigned long posByteEnd, + /* "dataRead.pyx":710 + * unsigned long record_byte_size, unsigned long posByteBeg, unsigned long nBytes, * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): * cdef np.ndarray buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array # <<<<<<<<<<<<<< * cdef unsigned long long i - * for i in range(numberOfRecords): + * cdef unsigned long posByteEnd = posByteBeg + nBytes */ - __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 725, __pyx_L1_error) + __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 710, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 725, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 710, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_numberOfRecords); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 725, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_numberOfRecords); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 710, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 725, __pyx_L1_error) + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 710, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 725, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 710, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 725, __pyx_L1_error) - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 725, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 710, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 710, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 725, __pyx_L1_error) + if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 710, __pyx_L1_error) __pyx_v_buf = ((PyArrayObject *)__pyx_t_4); __pyx_t_4 = 0; - /* "dataRead.pyx":727 + /* "dataRead.pyx":712 * cdef np.ndarray buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array * cdef unsigned long long i + * cdef unsigned long posByteEnd = posByteBeg + nBytes # <<<<<<<<<<<<<< + * for i in range(numberOfRecords): + * buf[i] = np.fromstring(bita[posByteBeg + record_byte_size * i:\ + */ + __pyx_v_posByteEnd = (__pyx_v_posByteBeg + __pyx_v_nBytes); + + /* "dataRead.pyx":713 + * cdef unsigned long long i + * cdef unsigned long posByteEnd = posByteBeg + nBytes * for i in range(numberOfRecords): # <<<<<<<<<<<<<< * buf[i] = np.fromstring(bita[posByteBeg + record_byte_size * i:\ * posByteEnd + record_byte_size * i], dtype=RecordFormat) @@ -10336,70 +10185,70 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *__pyx for (__pyx_t_7 = 0; __pyx_t_7 < __pyx_t_6; __pyx_t_7+=1) { __pyx_v_i = __pyx_t_7; - /* "dataRead.pyx":728 - * cdef unsigned long long i + /* "dataRead.pyx":714 + * cdef unsigned long posByteEnd = posByteBeg + nBytes * for i in range(numberOfRecords): * buf[i] = np.fromstring(bita[posByteBeg + record_byte_size * i:\ # <<<<<<<<<<<<<< * posByteEnd + record_byte_size * i], dtype=RecordFormat) * if swap == 0: */ - __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 728, __pyx_L1_error) + __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 714, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_fromstring); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 728, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_fromstring); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 714, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - /* "dataRead.pyx":729 + /* "dataRead.pyx":715 * for i in range(numberOfRecords): * buf[i] = np.fromstring(bita[posByteBeg + record_byte_size * i:\ * posByteEnd + record_byte_size * i], dtype=RecordFormat) # <<<<<<<<<<<<<< * if swap == 0: * return buf */ - __pyx_t_4 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_bita + (__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i)), (__pyx_v_posByteEnd + (__pyx_v_record_byte_size * __pyx_v_i)) - (__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 728, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_bita + (__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i)), (__pyx_v_posByteEnd + (__pyx_v_record_byte_size * __pyx_v_i)) - (__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 714, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - /* "dataRead.pyx":728 - * cdef unsigned long long i + /* "dataRead.pyx":714 + * cdef unsigned long posByteEnd = posByteBeg + nBytes * for i in range(numberOfRecords): * buf[i] = np.fromstring(bita[posByteBeg + record_byte_size * i:\ # <<<<<<<<<<<<<< * posByteEnd + record_byte_size * i], dtype=RecordFormat) * if swap == 0: */ - __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 728, __pyx_L1_error) + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 714, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4); __pyx_t_4 = 0; - /* "dataRead.pyx":729 + /* "dataRead.pyx":715 * for i in range(numberOfRecords): * buf[i] = np.fromstring(bita[posByteBeg + record_byte_size * i:\ * posByteEnd + record_byte_size * i], dtype=RecordFormat) # <<<<<<<<<<<<<< * if swap == 0: * return buf */ - __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 729, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 715, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 729, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 715, __pyx_L1_error) - /* "dataRead.pyx":728 - * cdef unsigned long long i + /* "dataRead.pyx":714 + * cdef unsigned long posByteEnd = posByteBeg + nBytes * for i in range(numberOfRecords): * buf[i] = np.fromstring(bita[posByteBeg + record_byte_size * i:\ # <<<<<<<<<<<<<< * posByteEnd + record_byte_size * i], dtype=RecordFormat) * if swap == 0: */ - __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 728, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 714, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (unlikely(__Pyx_SetItemInt(((PyObject *)__pyx_v_buf), __pyx_v_i, __pyx_t_2, unsigned PY_LONG_LONG, 0, __Pyx_PyInt_From_unsigned_PY_LONG_LONG, 0, 0, 1) < 0)) __PYX_ERR(0, 728, __pyx_L1_error) + if (unlikely(__Pyx_SetItemInt(((PyObject *)__pyx_v_buf), __pyx_v_i, __pyx_t_2, unsigned PY_LONG_LONG, 0, __Pyx_PyInt_From_unsigned_PY_LONG_LONG, 0, 0, 1) < 0)) __PYX_ERR(0, 714, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; } - /* "dataRead.pyx":730 + /* "dataRead.pyx":716 * buf[i] = np.fromstring(bita[posByteBeg + record_byte_size * i:\ * posByteEnd + record_byte_size * i], dtype=RecordFormat) * if swap == 0: # <<<<<<<<<<<<<< @@ -10409,7 +10258,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *__pyx __pyx_t_8 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_8) { - /* "dataRead.pyx":731 + /* "dataRead.pyx":717 * posByteEnd + record_byte_size * i], dtype=RecordFormat) * if swap == 0: * return buf # <<<<<<<<<<<<<< @@ -10421,7 +10270,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *__pyx __pyx_r = ((PyObject *)__pyx_v_buf); goto __pyx_L0; - /* "dataRead.pyx":730 + /* "dataRead.pyx":716 * buf[i] = np.fromstring(bita[posByteBeg + record_byte_size * i:\ * posByteEnd + record_byte_size * i], dtype=RecordFormat) * if swap == 0: # <<<<<<<<<<<<<< @@ -10430,14 +10279,14 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *__pyx */ } - /* "dataRead.pyx":733 + /* "dataRead.pyx":719 * return buf * else: * return buf.byteswap() # <<<<<<<<<<<<<< */ /*else*/ { __Pyx_XDECREF(__pyx_r); - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_buf), __pyx_n_s_byteswap); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 733, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_buf), __pyx_n_s_byteswap); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 719, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_3 = NULL; if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) { @@ -10450,10 +10299,10 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *__pyx } } if (__pyx_t_3) { - __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 733, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 719, __pyx_L1_error) __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; } else { - __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 733, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 719, __pyx_L1_error) } __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; @@ -10462,11 +10311,11 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *__pyx goto __pyx_L0; } - /* "dataRead.pyx":722 + /* "dataRead.pyx":707 * return buf * * cdef inline dataReadArray(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, unsigned long posByteEnd, + * unsigned long record_byte_size, unsigned long posByteBeg, unsigned long nBytes, * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): */ @@ -13009,6 +12858,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, {&__pyx_n_s_little, __pyx_k_little, sizeof(__pyx_k_little), 0, 0, 1, 1}, {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, + {&__pyx_n_s_nBytes, __pyx_k_nBytes, sizeof(__pyx_k_nBytes), 0, 0, 1, 1}, {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0}, {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0}, {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1}, @@ -13017,7 +12867,6 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_kp_s_numpy_core_multiarray_failed_to, __pyx_k_numpy_core_multiarray_failed_to, sizeof(__pyx_k_numpy_core_multiarray_failed_to), 0, 0, 1, 0}, {&__pyx_kp_s_numpy_core_umath_failed_to_impor, __pyx_k_numpy_core_umath_failed_to_impor, sizeof(__pyx_k_numpy_core_umath_failed_to_impor), 0, 0, 1, 0}, {&__pyx_n_s_posByteBeg, __pyx_k_posByteBeg, sizeof(__pyx_k_posByteBeg), 0, 0, 1, 1}, - {&__pyx_n_s_posByteEnd, __pyx_k_posByteEnd, sizeof(__pyx_k_posByteEnd), 0, 0, 1, 1}, {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, {&__pyx_n_s_record_byte_size, __pyx_k_record_byte_size, sizeof(__pyx_k_record_byte_size), 0, 0, 1, 1}, {&__pyx_n_s_signalDataType, __pyx_k_signalDataType, sizeof(__pyx_k_signalDataType), 0, 0, 1, 1}, @@ -13145,7 +12994,7 @@ static int __Pyx_InitCachedConstants(void) { * unsigned short signalDataType, str RecordFormat, unsigned long long numberOfRecords, * unsigned long record_byte_size, unsigned char bitOffset, */ - __pyx_tuple__10 = PyTuple_Pack(11, __pyx_n_s_tmp, __pyx_n_s_bitCount, __pyx_n_s_signalDataType, __pyx_n_s_RecordFormat, __pyx_n_s_numberOfRecords, __pyx_n_s_record_byte_size, __pyx_n_s_bitOffset, __pyx_n_s_posByteBeg, __pyx_n_s_posByteEnd, __pyx_n_s_array, __pyx_n_s_bita); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(0, 11, __pyx_L1_error) + __pyx_tuple__10 = PyTuple_Pack(11, __pyx_n_s_tmp, __pyx_n_s_bitCount, __pyx_n_s_signalDataType, __pyx_n_s_RecordFormat, __pyx_n_s_numberOfRecords, __pyx_n_s_record_byte_size, __pyx_n_s_bitOffset, __pyx_n_s_posByteBeg, __pyx_n_s_nBytes, __pyx_n_s_array, __pyx_n_s_bita); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(0, 11, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__10); __Pyx_GIVEREF(__pyx_tuple__10); __pyx_codeobj__11 = (PyObject*)__Pyx_PyCode_New(10, 0, 11, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__10, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_dataRead_pyx, __pyx_n_s_dataRead, 11, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__11)) __PYX_ERR(0, 11, __pyx_L1_error) @@ -14731,21 +14580,6 @@ static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject } #endif -/* None */ - static CYTHON_INLINE long __Pyx_div_long(long a, long b) { - long q = a / b; - long r = a - q*b; - q -= ((r != 0) & ((r ^ b) < 0)); - return q; -} - -/* None */ - static CYTHON_INLINE long __Pyx_mod_long(long a, long b) { - long r = a % b; - r += ((r != 0) & ((r ^ b) < 0)) * b; - return r; -} - /* SetItemInt */ static int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) { int r; diff --git a/dataRead.pyx b/dataRead.pyx index 475a673..8609ede 100644 --- a/dataRead.pyx +++ b/dataRead.pyx @@ -11,7 +11,7 @@ from libc.string cimport memcpy def dataRead(bytes tmp, unsigned short bitCount, unsigned short signalDataType, str RecordFormat, unsigned long long numberOfRecords, unsigned long record_byte_size, unsigned char bitOffset, - unsigned long posByteBeg, unsigned long posByteEnd, array): + unsigned long posByteBeg, unsigned long nBytes, array): """dataRead function to read in cython a channel from a byte stream Parameters @@ -33,8 +33,8 @@ def dataRead(bytes tmp, unsigned short bitCount, bit offset of data in C aligned bytes posByteBeg : unsigned long beginning byte position of channel in record - posByteEnd : unsigned long - ending byte position of channel in record + nBytes : unsigned long + bytes length of channel in record array : boolean reads an array, not a vector @@ -47,7 +47,7 @@ def dataRead(bytes tmp, unsigned short bitCount, if not array: if 'V' in RecordFormat or 'S' in RecordFormat or RecordFormat is None: return dataReadByte(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset) + record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) elif signalDataType in (4, 5) and bitCount == 32: # float if (byteorder == 'little' and signalDataType == 4) or \ (byteorder == 'big' and signalDataType == 5): @@ -90,45 +90,45 @@ def dataRead(bytes tmp, unsigned short bitCount, if (byteorder == 'little' and signalDataType == 0) or \ (byteorder == 'big' and signalDataType == 1): return dataReadUInt(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, bitCount, bitOffset, 0) + record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) else: # swap bytes return dataReadUInt(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, bitCount, bitOffset, 1) + record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int if (byteorder == 'little' and signalDataType == 2) or \ (byteorder == 'big' and signalDataType == 3): return dataReadInt(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, bitCount, bitOffset, 0) + record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) else: # swap bytes return dataReadInt(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, bitCount, bitOffset, 1) + record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long if (byteorder == 'little' and signalDataType == 0) or \ (byteorder == 'big' and signalDataType == 1): return dataReadULongLong(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, bitCount, bitOffset, 0) + record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) else: # swap bytes return dataReadULongLong(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, bitCount, bitOffset, 1) + record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long if (byteorder == 'little' and signalDataType == 0) or \ (byteorder == 'big' and signalDataType == 1): return dataReadLongLong(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, bitCount, bitOffset, 0) + record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) else: # swap bytes return dataReadLongLong(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, bitCount, bitOffset, 1) + record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) else: return dataReadByte(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset) + record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) else: # array if (byteorder == 'little' and signalDataType in (0, 2, 4)) or \ (byteorder == 'big' and signalDataType in (1, 3, 5)): return dataReadArray(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset, 0) + record_byte_size, posByteBeg, nBytes, bitCount, bitOffset, 0) else: # swap bytes return dataReadArray(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, posByteEnd, bitCount, bitOffset, 1) + record_byte_size, posByteBeg, nBytes, bitCount, bitOffset, 1) cdef inline dataReadFloat(const char* bita, str RecordFormat, unsigned long long numberOfRecords, @@ -298,18 +298,13 @@ cdef inline dataReadShort(const char* bita, str RecordFormat, unsigned long long cdef inline dataReadUInt(const char* bita, str RecordFormat, unsigned long long numberOfRecords, unsigned long record_byte_size, unsigned long posByteBeg, - unsigned long bitCount, unsigned char bitOffset, unsigned char swap): + unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): cdef np.ndarray[np.uint32_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array cdef unsigned long long i cdef unsigned int mask = ((1 << bitCount) - 1) cdef unsigned int temp4byte = 0 - cdef unsigned char nBytes = 0 cdef char temp4[4] cdef char temp3[3] - if bitCount + bitOffset > 24: - nBytes = 4 - else: - nBytes = 3 if bitCount == 32: for i in range(numberOfRecords): memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) @@ -368,21 +363,16 @@ cdef inline dataReadUInt(const char* bita, str RecordFormat, unsigned long long cdef inline dataReadInt(const char* bita, str RecordFormat, unsigned long long numberOfRecords, unsigned long record_byte_size, unsigned long posByteBeg, - unsigned long bitCount, unsigned char bitOffset, unsigned char swap): + unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): cdef np.ndarray[np.int32_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array cdef unsigned long long i cdef int mask = ((1 << bitCount) - 1) cdef int temp4byte = 0 - cdef unsigned char nBytes = 0 cdef int signBit = 0 cdef int signBitMask = (1 << (bitCount-1)) cdef int signExtend = ((1 << (32 - bitCount)) - 1) << bitCount cdef char temp4[4] cdef char temp3[3] - if bitCount + bitOffset > 24: - nBytes = 4 - else: - nBytes = 3 if bitCount == 32: for i in range(numberOfRecords): memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) @@ -452,18 +442,15 @@ cdef inline dataReadInt(const char* bita, str RecordFormat, unsigned long long n cdef inline dataReadULongLong(const char* bita, str RecordFormat, unsigned long long numberOfRecords, unsigned long record_byte_size, unsigned long posByteBeg, - unsigned long bitCount, unsigned char bitOffset, unsigned char swap): + unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): cdef np.ndarray[np.uint64_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array cdef unsigned long long i cdef unsigned long long mask = ((1 << bitCount) - 1) cdef unsigned long long temp8byte = 0 - cdef unsigned char nBytes = bitCount + bitOffset // 8 cdef char temp8[8] cdef char temp7[7] cdef char temp6[6] cdef char temp5[5] - if bitCount + bitOffset % 8 > 0: - nBytes += 1 if bitCount == 64: for i in range(numberOfRecords): memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) @@ -568,12 +555,11 @@ cdef inline dataReadULongLong(const char* bita, str RecordFormat, unsigned long cdef inline dataReadLongLong(const char* bita, str RecordFormat, unsigned long long numberOfRecords, unsigned long record_byte_size, unsigned long posByteBeg, - unsigned long bitCount, unsigned char bitOffset, unsigned char swap): + unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): cdef np.ndarray[np.int64_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array cdef unsigned long long i cdef long long mask = ((1 << bitCount) - 1) cdef long long temp8byte = 0 - cdef unsigned char nBytes = bitCount + bitOffset // 8 cdef long signBit = 0 cdef long long signBitMask = (1 << (bitCount-1)) cdef long long signExtend = ((1 << (64 - bitCount)) - 1) << bitCount @@ -581,8 +567,6 @@ cdef inline dataReadLongLong(const char* bita, str RecordFormat, unsigned long l cdef char temp7[7] cdef char temp6[6] cdef char temp5[5] - if bitCount + bitOffset % 8 > 0: - nBytes += 1 if bitCount == 64: for i in range(numberOfRecords): memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) @@ -710,20 +694,22 @@ cdef inline dataReadLongLong(const char* bita, str RecordFormat, unsigned long l return buf cdef inline dataReadByte(const char* bita, str RecordFormat, unsigned long long numberOfRecords, - unsigned long record_byte_size, unsigned long posByteBeg, unsigned long posByteEnd, + unsigned long record_byte_size, unsigned long posByteBeg, unsigned long nBytes, unsigned long bitCount, unsigned char bitOffset): cdef np.ndarray buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array cdef unsigned long long i + cdef unsigned long posByteEnd = posByteBeg + nBytes for i in range(numberOfRecords): buf[i] = bytes(bita[posByteBeg + record_byte_size * i:\ posByteEnd + record_byte_size * i]) return buf cdef inline dataReadArray(const char* bita, str RecordFormat, unsigned long long numberOfRecords, - unsigned long record_byte_size, unsigned long posByteBeg, unsigned long posByteEnd, + unsigned long record_byte_size, unsigned long posByteBeg, unsigned long nBytes, unsigned long bitCount, unsigned char bitOffset, unsigned char swap): cdef np.ndarray buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array cdef unsigned long long i + cdef unsigned long posByteEnd = posByteBeg + nBytes for i in range(numberOfRecords): buf[i] = np.fromstring(bita[posByteBeg + record_byte_size * i:\ posByteEnd + record_byte_size * i], dtype=RecordFormat) diff --git a/mdfreader/mdf3reader.py b/mdfreader/mdf3reader.py index 910b542..9750402 100644 --- a/mdfreader/mdf3reader.py +++ b/mdfreader/mdf3reader.py @@ -546,7 +546,7 @@ def readSortedRecord(self, fid, pointer, channelSet=None): self.CGrecordLength, chan.bitOffset, chan.posByteBeg, - chan.posByteEnd, 0) + chan.nBytes, 0) self[id].bit_masking_needed = False # masking already considered in dataRead previous_index += nrecord_chunk return rec diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index e00b7b8..8500079 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -972,7 +972,7 @@ def read_channels_from_bytes(self, bita, info, channelSet=None, nrecords=None, self[chan].nativedataFormat(info), nrecords, self.CGrecordLength, self[chan].bitOffset(info), self[chan].posByteBeg(info), - self[chan].posByteEnd(info), array_flag) + self[chan].nBytes(info), array_flag) return buf else: return self.read_channels_from_bytes_fallback(bita, info, channelSet, nrecords, dtype) From abc7323446c2f9027186daf972fe562b45ae213b Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Mon, 24 Sep 2018 23:46:24 +0200 Subject: [PATCH 09/61] removed else: for cythonize --- setup.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 33a1b38..f20ea41 100644 --- a/setup.py +++ b/setup.py @@ -6,16 +6,14 @@ try: from Cython.Build import cythonize + # If we successfully imported Cython, look for a .pyx file import numpy - ext_modules = cythonize('dataRead', include_path=[numpy.get_include()]) + ext_modules = cythonize('dataRead.pyx', include_path=[numpy.get_include()], gdb_debug=True) except: # If we couldn't import Cython, use the normal setuptools # and look for a pre-compiled .c file instead of a .pyx file from setuptools.command.build_ext import build_ext ext_modules = [Extension("dataRead", ["dataRead.c"])] -else: - # If we successfully imported Cython, look for a .pyx file - ext_modules = [Extension("dataRead", ["dataRead.pyx"])] name = 'mdfreader' From beffcbb44f642a304eaaff61972dc479c000a97c Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Tue, 25 Sep 2018 21:18:29 +0200 Subject: [PATCH 10/61] nbytes instead of bitcount for dataRead selection --- dataRead.pyx | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/dataRead.pyx b/dataRead.pyx index 8609ede..121b2a3 100644 --- a/dataRead.pyx +++ b/dataRead.pyx @@ -48,7 +48,7 @@ def dataRead(bytes tmp, unsigned short bitCount, if 'V' in RecordFormat or 'S' in RecordFormat or RecordFormat is None: return dataReadByte(bita, RecordFormat, numberOfRecords, record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) - elif signalDataType in (4, 5) and bitCount == 32: # float + elif signalDataType in (4, 5) and nBytes == 4: # float if (byteorder == 'little' and signalDataType == 4) or \ (byteorder == 'big' and signalDataType == 5): return dataReadFloat(bita, RecordFormat, numberOfRecords, @@ -56,7 +56,7 @@ def dataRead(bytes tmp, unsigned short bitCount, else: # swap bytes return dataReadFloat(bita, RecordFormat, numberOfRecords, record_byte_size, posByteBeg, 1) - elif signalDataType in (4, 5) and bitCount == 64: # double + elif signalDataType in (4, 5) and nBytes == 8: # double if (byteorder == 'little' and signalDataType == 4) or \ (byteorder == 'big' and signalDataType == 5): return dataReadDouble(bita, RecordFormat, numberOfRecords, @@ -64,13 +64,13 @@ def dataRead(bytes tmp, unsigned short bitCount, else: # swap bytes return dataReadDouble(bita, RecordFormat, numberOfRecords, record_byte_size, posByteBeg, 1) - elif signalDataType in (0, 1, 13) and bitCount + bitOffset <= 8: # unsigned char + elif signalDataType in (0, 1, 13) and nBytes == 1: # unsigned char return dataReadUChar(bita, RecordFormat, numberOfRecords, record_byte_size, posByteBeg, bitCount, bitOffset) - elif signalDataType in (2, 3) and bitCount + bitOffset <= 8: # signed char + elif signalDataType in (2, 3) and nBytes == 1: # signed char return dataReadChar(bita, RecordFormat, numberOfRecords, record_byte_size, posByteBeg, bitCount, bitOffset) - elif signalDataType in (0, 1, 13, 14) and bitCount + bitOffset <=16: # unsigned short + elif signalDataType in (0, 1, 13, 14) and nBytes <= 2: # unsigned short if (byteorder == 'little' and signalDataType == 0) or \ (byteorder == 'big' and signalDataType == 1): return dataReadUShort(bita, RecordFormat, numberOfRecords, @@ -78,7 +78,7 @@ def dataRead(bytes tmp, unsigned short bitCount, else: # swap bytes return dataReadUShort(bita, RecordFormat, numberOfRecords, record_byte_size, posByteBeg, bitCount, bitOffset, 1) - elif signalDataType in (2, 3) and bitCount + bitOffset <= 16: # signed short + elif signalDataType in (2, 3) and nBytes <= 2: # signed short if (byteorder == 'little' and signalDataType == 2) or \ (byteorder == 'big' and signalDataType == 3): return dataReadShort(bita, RecordFormat, numberOfRecords, @@ -86,7 +86,7 @@ def dataRead(bytes tmp, unsigned short bitCount, else: # swap bytes return dataReadShort(bita, RecordFormat, numberOfRecords, record_byte_size, posByteBeg, bitCount, bitOffset, 1) - elif signalDataType in (0, 1, 14) and bitCount + bitOffset <=32: # unsigned int + elif signalDataType in (0, 1, 14) and nBytes <= 4: # unsigned int if (byteorder == 'little' and signalDataType == 0) or \ (byteorder == 'big' and signalDataType == 1): return dataReadUInt(bita, RecordFormat, numberOfRecords, @@ -94,7 +94,7 @@ def dataRead(bytes tmp, unsigned short bitCount, else: # swap bytes return dataReadUInt(bita, RecordFormat, numberOfRecords, record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int + elif signalDataType in (2, 3) and nBytes <= 4: # signed int if (byteorder == 'little' and signalDataType == 2) or \ (byteorder == 'big' and signalDataType == 3): return dataReadInt(bita, RecordFormat, numberOfRecords, @@ -102,7 +102,7 @@ def dataRead(bytes tmp, unsigned short bitCount, else: # swap bytes return dataReadInt(bita, RecordFormat, numberOfRecords, record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long + elif signalDataType in (0, 1) and nBytes <= 8: # unsigned long long if (byteorder == 'little' and signalDataType == 0) or \ (byteorder == 'big' and signalDataType == 1): return dataReadULongLong(bita, RecordFormat, numberOfRecords, @@ -110,7 +110,7 @@ def dataRead(bytes tmp, unsigned short bitCount, else: # swap bytes return dataReadULongLong(bita, RecordFormat, numberOfRecords, record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long + elif signalDataType in (2, 3) and nBytes <= 8: # signed long long if (byteorder == 'little' and signalDataType == 0) or \ (byteorder == 'big' and signalDataType == 1): return dataReadLongLong(bita, RecordFormat, numberOfRecords, From 1b39150c9d84dd9387f31dafb5325a04d7d7f965 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Mon, 1 Oct 2018 17:56:39 +0200 Subject: [PATCH 11/61] change to version 2.8 --- mdfreader/__init__.py | 2 +- mdfreader/mdfinfo4.py | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mdfreader/__init__.py b/mdfreader/__init__.py index 1313147..ddd2be0 100644 --- a/mdfreader/__init__.py +++ b/mdfreader/__init__.py @@ -16,7 +16,7 @@ __author__ = 'Aymeric Rateau (aymeric.rateau@gmail.com)' __copyright__ = 'Copyright (c) 2017 Aymeric Rateau' __license__ = 'GPLV3' -__version__ = "2.7.8" +__version__ = "2.8" from .mdfreader import mdf, mdfinfo diff --git a/mdfreader/mdfinfo4.py b/mdfreader/mdfinfo4.py index eb9ae1e..0b7894c 100644 --- a/mdfreader/mdfinfo4.py +++ b/mdfreader/mdfinfo4.py @@ -541,7 +541,7 @@ def load(self, data, MDType): tool_vendor = SubElement(root, 'tool_vendor') tool_vendor.text = 'mdfreader is under GPL V3' tool_version = SubElement(root, 'tool_version') - tool_version.text = '2.6' + tool_version.text = '2.8' data = b''.join([tostring(root), b'\0']) block_id = b'##MD' # make sure block is multiple of 8 diff --git a/setup.py b/setup.py index f20ea41..fd2ab68 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ name = 'mdfreader' -version = '2.7.8' +version = '2.8' description = 'A Measured Data Format file parser' From c4b0db89700dd0cda7f7ac1b6f51951026ef2500 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Mon, 1 Oct 2018 20:52:40 +0200 Subject: [PATCH 12/61] plot: handled case where no master channel present in datagroup, replace master by arange --- mdfreader/mdfreader.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/mdfreader/mdfreader.py b/mdfreader/mdfreader.py index f5dff24..1c01450 100644 --- a/mdfreader/mdfreader.py +++ b/mdfreader/mdfreader.py @@ -492,7 +492,7 @@ def plot(self, channel_name_list_of_list): try: from mpldatacursor import datacursor except ImportError: - print('no cursor available, please install properly mpldatacursor') + warn('no cursor available, please install properly mpldatacursor') if isinstance(channel_name_list_of_list, str): channel_name_list_of_list = [channel_name_list_of_list] # converts in list for channel_name_list in channel_name_list_of_list: @@ -509,15 +509,21 @@ def plot(self, channel_name_list_of_list): masterName = list(self.masterChannelList)[0] if not masterName: # resampled channels, only one time channel probably called 'master' masterName = 'master' + master_data = self.getChannelData(master_name) + if master_data is None: # no master channel + master_data = arange(0, len(data), 1) if masterName in self.masterChannelList: # time channel properly defined - plt.plot(self.getChannelData(masterName), data, label=channelName) + plt.plot(master_data, data, label=channelName) plt.xlabel('{0} [{1}]'.format(masterName, self.getChannelUnit(masterName))) else: # no time channel found plt.plot(data) else: # not resampled master_name = self.getChannelMaster(channelName) + master_data = self.getChannelData(master_name) + if master_data is None: # no master channel + master_data = arange(0, len(data), 1) if master_name in self.masterChannelList: # master channel is proper channel name - plt.plot(self.getChannelData(master_name), data, label=channelName) + plt.plot(master_data, data, label=channelName) plt.xlabel('{0} [{1}]'.format(master_name, self.getChannelUnit(master_name))) else: plt.plot(data) @@ -532,7 +538,10 @@ def plot(self, channel_name_list_of_list): plt.grid(True) plt.legend(loc="upper left", frameon=False) plt.title('') - datacursor() + try: + datacursor() + except: + warn('No cursor , mpldatacursor not installed') plt.show() return fig From 393bf0071ff77a299c5a2617f58185ced059a72f Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Mon, 1 Oct 2018 20:53:11 +0200 Subject: [PATCH 13/61] changed to version 2.8 --- mdfconverter/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mdfconverter/__init__.py b/mdfconverter/__init__.py index ed948ea..a67a926 100644 --- a/mdfconverter/__init__.py +++ b/mdfconverter/__init__.py @@ -12,4 +12,4 @@ # along with this program. If not, see http://www.gnu.org/licenses. # # ---------------------------------------------------------------------- -__version__ = "2.7.8" +__version__ = "2.8" From c31a1a135adb0b518836ea9be5307e60bc8958ba Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Mon, 1 Oct 2018 20:54:00 +0200 Subject: [PATCH 14/61] changed from bitCount to nByte input argument --- dataRead.c | 172 ++++++++++++++++++++++++++--------------------------- 1 file changed, 86 insertions(+), 86 deletions(-) diff --git a/dataRead.c b/dataRead.c index a4096a0..d9a8f16 100644 --- a/dataRead.c +++ b/dataRead.c @@ -1985,7 +1985,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * if 'V' in RecordFormat or 'S' in RecordFormat or RecordFormat is None: * return dataReadByte(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) - * elif signalDataType in (4, 5) and bitCount == 32: # float + * elif signalDataType in (4, 5) and nBytes == 4: # float */ __Pyx_XDECREF(__pyx_r); @@ -1993,7 +1993,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * if 'V' in RecordFormat or 'S' in RecordFormat or RecordFormat is None: * return dataReadByte(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) # <<<<<<<<<<<<<< - * elif signalDataType in (4, 5) and bitCount == 32: # float + * elif signalDataType in (4, 5) and nBytes == 4: # float * if (byteorder == 'little' and signalDataType == 4) or \ */ __pyx_t_5 = __pyx_f_8dataRead_dataReadByte(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_nBytes, __pyx_v_bitCount, __pyx_v_bitOffset); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 49, __pyx_L1_error) @@ -2014,7 +2014,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":51 * return dataReadByte(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) - * elif signalDataType in (4, 5) and bitCount == 32: # float # <<<<<<<<<<<<<< + * elif signalDataType in (4, 5) and nBytes == 4: # float # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 4) or \ * (byteorder == 'big' and signalDataType == 5): */ @@ -2033,14 +2033,14 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_2; goto __pyx_L8_bool_binop_done; } - __pyx_t_2 = ((__pyx_v_bitCount == 32) != 0); + __pyx_t_2 = ((__pyx_v_nBytes == 4) != 0); __pyx_t_3 = __pyx_t_2; __pyx_L8_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":52 * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) - * elif signalDataType in (4, 5) and bitCount == 32: # float + * elif signalDataType in (4, 5) and nBytes == 4: # float * if (byteorder == 'little' and signalDataType == 4) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 5): * return dataReadFloat(bita, RecordFormat, numberOfRecords, @@ -2062,7 +2062,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L12_next_or:; /* "dataRead.pyx":53 - * elif signalDataType in (4, 5) and bitCount == 32: # float + * elif signalDataType in (4, 5) and nBytes == 4: # float * if (byteorder == 'little' and signalDataType == 4) or \ * (byteorder == 'big' and signalDataType == 5): # <<<<<<<<<<<<<< * return dataReadFloat(bita, RecordFormat, numberOfRecords, @@ -2083,7 +2083,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":52 * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) - * elif signalDataType in (4, 5) and bitCount == 32: # float + * elif signalDataType in (4, 5) and nBytes == 4: # float * if (byteorder == 'little' and signalDataType == 4) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 5): * return dataReadFloat(bita, RecordFormat, numberOfRecords, @@ -2114,7 +2114,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":52 * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) - * elif signalDataType in (4, 5) and bitCount == 32: # float + * elif signalDataType in (4, 5) and nBytes == 4: # float * if (byteorder == 'little' and signalDataType == 4) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 5): * return dataReadFloat(bita, RecordFormat, numberOfRecords, @@ -2126,7 +2126,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadFloat(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< * record_byte_size, posByteBeg, 1) - * elif signalDataType in (4, 5) and bitCount == 64: # double + * elif signalDataType in (4, 5) and nBytes == 8: # double */ /*else*/ { __Pyx_XDECREF(__pyx_r); @@ -2135,7 +2135,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadFloat(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, 1) # <<<<<<<<<<<<<< - * elif signalDataType in (4, 5) and bitCount == 64: # double + * elif signalDataType in (4, 5) and nBytes == 8: # double * if (byteorder == 'little' and signalDataType == 4) or \ */ __pyx_t_5 = __pyx_f_8dataRead_dataReadFloat(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 57, __pyx_L1_error) @@ -2148,7 +2148,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":51 * return dataReadByte(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) - * elif signalDataType in (4, 5) and bitCount == 32: # float # <<<<<<<<<<<<<< + * elif signalDataType in (4, 5) and nBytes == 4: # float # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 4) or \ * (byteorder == 'big' and signalDataType == 5): */ @@ -2157,7 +2157,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":59 * return dataReadFloat(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, 1) - * elif signalDataType in (4, 5) and bitCount == 64: # double # <<<<<<<<<<<<<< + * elif signalDataType in (4, 5) and nBytes == 8: # double # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 4) or \ * (byteorder == 'big' and signalDataType == 5): */ @@ -2176,14 +2176,14 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_4; goto __pyx_L15_bool_binop_done; } - __pyx_t_4 = ((__pyx_v_bitCount == 64) != 0); + __pyx_t_4 = ((__pyx_v_nBytes == 8) != 0); __pyx_t_3 = __pyx_t_4; __pyx_L15_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":60 * record_byte_size, posByteBeg, 1) - * elif signalDataType in (4, 5) and bitCount == 64: # double + * elif signalDataType in (4, 5) and nBytes == 8: # double * if (byteorder == 'little' and signalDataType == 4) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 5): * return dataReadDouble(bita, RecordFormat, numberOfRecords, @@ -2205,7 +2205,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L19_next_or:; /* "dataRead.pyx":61 - * elif signalDataType in (4, 5) and bitCount == 64: # double + * elif signalDataType in (4, 5) and nBytes == 8: # double * if (byteorder == 'little' and signalDataType == 4) or \ * (byteorder == 'big' and signalDataType == 5): # <<<<<<<<<<<<<< * return dataReadDouble(bita, RecordFormat, numberOfRecords, @@ -2226,7 +2226,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":60 * record_byte_size, posByteBeg, 1) - * elif signalDataType in (4, 5) and bitCount == 64: # double + * elif signalDataType in (4, 5) and nBytes == 8: # double * if (byteorder == 'little' and signalDataType == 4) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 5): * return dataReadDouble(bita, RecordFormat, numberOfRecords, @@ -2257,7 +2257,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":60 * record_byte_size, posByteBeg, 1) - * elif signalDataType in (4, 5) and bitCount == 64: # double + * elif signalDataType in (4, 5) and nBytes == 8: # double * if (byteorder == 'little' and signalDataType == 4) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 5): * return dataReadDouble(bita, RecordFormat, numberOfRecords, @@ -2269,7 +2269,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadDouble(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< * record_byte_size, posByteBeg, 1) - * elif signalDataType in (0, 1, 13) and bitCount + bitOffset <= 8: # unsigned char + * elif signalDataType in (0, 1, 13) and nBytes == 1: # unsigned char */ /*else*/ { __Pyx_XDECREF(__pyx_r); @@ -2278,7 +2278,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadDouble(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, 1) # <<<<<<<<<<<<<< - * elif signalDataType in (0, 1, 13) and bitCount + bitOffset <= 8: # unsigned char + * elif signalDataType in (0, 1, 13) and nBytes == 1: # unsigned char * return dataReadUChar(bita, RecordFormat, numberOfRecords, */ __pyx_t_5 = __pyx_f_8dataRead_dataReadDouble(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 65, __pyx_L1_error) @@ -2291,7 +2291,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":59 * return dataReadFloat(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, 1) - * elif signalDataType in (4, 5) and bitCount == 64: # double # <<<<<<<<<<<<<< + * elif signalDataType in (4, 5) and nBytes == 8: # double # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 4) or \ * (byteorder == 'big' and signalDataType == 5): */ @@ -2300,7 +2300,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":67 * return dataReadDouble(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, 1) - * elif signalDataType in (0, 1, 13) and bitCount + bitOffset <= 8: # unsigned char # <<<<<<<<<<<<<< + * elif signalDataType in (0, 1, 13) and nBytes == 1: # unsigned char # <<<<<<<<<<<<<< * return dataReadUChar(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset) */ @@ -2320,25 +2320,25 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_2; goto __pyx_L22_bool_binop_done; } - __pyx_t_2 = (((__pyx_v_bitCount + __pyx_v_bitOffset) <= 8) != 0); + __pyx_t_2 = ((__pyx_v_nBytes == 1) != 0); __pyx_t_3 = __pyx_t_2; __pyx_L22_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":68 * record_byte_size, posByteBeg, 1) - * elif signalDataType in (0, 1, 13) and bitCount + bitOffset <= 8: # unsigned char + * elif signalDataType in (0, 1, 13) and nBytes == 1: # unsigned char * return dataReadUChar(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 8: # signed char + * elif signalDataType in (2, 3) and nBytes == 1: # signed char */ __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":69 - * elif signalDataType in (0, 1, 13) and bitCount + bitOffset <= 8: # unsigned char + * elif signalDataType in (0, 1, 13) and nBytes == 1: # unsigned char * return dataReadUChar(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset) # <<<<<<<<<<<<<< - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 8: # signed char + * elif signalDataType in (2, 3) and nBytes == 1: # signed char * return dataReadChar(bita, RecordFormat, numberOfRecords, */ __pyx_t_5 = __pyx_f_8dataRead_dataReadUChar(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 68, __pyx_L1_error) @@ -2350,7 +2350,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":67 * return dataReadDouble(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, 1) - * elif signalDataType in (0, 1, 13) and bitCount + bitOffset <= 8: # unsigned char # <<<<<<<<<<<<<< + * elif signalDataType in (0, 1, 13) and nBytes == 1: # unsigned char # <<<<<<<<<<<<<< * return dataReadUChar(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset) */ @@ -2359,7 +2359,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":70 * return dataReadUChar(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 8: # signed char # <<<<<<<<<<<<<< + * elif signalDataType in (2, 3) and nBytes == 1: # signed char # <<<<<<<<<<<<<< * return dataReadChar(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset) */ @@ -2378,25 +2378,25 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_4; goto __pyx_L24_bool_binop_done; } - __pyx_t_4 = (((__pyx_v_bitCount + __pyx_v_bitOffset) <= 8) != 0); + __pyx_t_4 = ((__pyx_v_nBytes == 1) != 0); __pyx_t_3 = __pyx_t_4; __pyx_L24_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":71 * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 8: # signed char + * elif signalDataType in (2, 3) and nBytes == 1: # signed char * return dataReadChar(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (0, 1, 13, 14) and bitCount + bitOffset <=16: # unsigned short + * elif signalDataType in (0, 1, 13, 14) and nBytes <= 2: # unsigned short */ __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":72 - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 8: # signed char + * elif signalDataType in (2, 3) and nBytes == 1: # signed char * return dataReadChar(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset) # <<<<<<<<<<<<<< - * elif signalDataType in (0, 1, 13, 14) and bitCount + bitOffset <=16: # unsigned short + * elif signalDataType in (0, 1, 13, 14) and nBytes <= 2: # unsigned short * if (byteorder == 'little' and signalDataType == 0) or \ */ __pyx_t_5 = __pyx_f_8dataRead_dataReadChar(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 71, __pyx_L1_error) @@ -2408,7 +2408,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":70 * return dataReadUChar(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 8: # signed char # <<<<<<<<<<<<<< + * elif signalDataType in (2, 3) and nBytes == 1: # signed char # <<<<<<<<<<<<<< * return dataReadChar(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset) */ @@ -2417,7 +2417,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":73 * return dataReadChar(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (0, 1, 13, 14) and bitCount + bitOffset <=16: # unsigned short # <<<<<<<<<<<<<< + * elif signalDataType in (0, 1, 13, 14) and nBytes <= 2: # unsigned short # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): */ @@ -2438,14 +2438,14 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_2; goto __pyx_L26_bool_binop_done; } - __pyx_t_2 = (((__pyx_v_bitCount + __pyx_v_bitOffset) <= 16) != 0); + __pyx_t_2 = ((__pyx_v_nBytes <= 2) != 0); __pyx_t_3 = __pyx_t_2; __pyx_L26_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":74 * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (0, 1, 13, 14) and bitCount + bitOffset <=16: # unsigned short + * elif signalDataType in (0, 1, 13, 14) and nBytes <= 2: # unsigned short * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadUShort(bita, RecordFormat, numberOfRecords, @@ -2467,7 +2467,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L30_next_or:; /* "dataRead.pyx":75 - * elif signalDataType in (0, 1, 13, 14) and bitCount + bitOffset <=16: # unsigned short + * elif signalDataType in (0, 1, 13, 14) and nBytes <= 2: # unsigned short * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): # <<<<<<<<<<<<<< * return dataReadUShort(bita, RecordFormat, numberOfRecords, @@ -2488,7 +2488,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":74 * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (0, 1, 13, 14) and bitCount + bitOffset <=16: # unsigned short + * elif signalDataType in (0, 1, 13, 14) and nBytes <= 2: # unsigned short * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadUShort(bita, RecordFormat, numberOfRecords, @@ -2519,7 +2519,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":74 * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (0, 1, 13, 14) and bitCount + bitOffset <=16: # unsigned short + * elif signalDataType in (0, 1, 13, 14) and nBytes <= 2: # unsigned short * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadUShort(bita, RecordFormat, numberOfRecords, @@ -2531,7 +2531,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadUShort(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 16: # signed short + * elif signalDataType in (2, 3) and nBytes <= 2: # signed short */ /*else*/ { __Pyx_XDECREF(__pyx_r); @@ -2540,7 +2540,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadUShort(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, 1) # <<<<<<<<<<<<<< - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 16: # signed short + * elif signalDataType in (2, 3) and nBytes <= 2: # signed short * if (byteorder == 'little' and signalDataType == 2) or \ */ __pyx_t_5 = __pyx_f_8dataRead_dataReadUShort(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 79, __pyx_L1_error) @@ -2553,7 +2553,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":73 * return dataReadChar(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (0, 1, 13, 14) and bitCount + bitOffset <=16: # unsigned short # <<<<<<<<<<<<<< + * elif signalDataType in (0, 1, 13, 14) and nBytes <= 2: # unsigned short # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): */ @@ -2562,7 +2562,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":81 * return dataReadUShort(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 16: # signed short # <<<<<<<<<<<<<< + * elif signalDataType in (2, 3) and nBytes <= 2: # signed short # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 2) or \ * (byteorder == 'big' and signalDataType == 3): */ @@ -2581,14 +2581,14 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_4; goto __pyx_L33_bool_binop_done; } - __pyx_t_4 = (((__pyx_v_bitCount + __pyx_v_bitOffset) <= 16) != 0); + __pyx_t_4 = ((__pyx_v_nBytes <= 2) != 0); __pyx_t_3 = __pyx_t_4; __pyx_L33_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":82 * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 16: # signed short + * elif signalDataType in (2, 3) and nBytes <= 2: # signed short * if (byteorder == 'little' and signalDataType == 2) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 3): * return dataReadShort(bita, RecordFormat, numberOfRecords, @@ -2610,7 +2610,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L37_next_or:; /* "dataRead.pyx":83 - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 16: # signed short + * elif signalDataType in (2, 3) and nBytes <= 2: # signed short * if (byteorder == 'little' and signalDataType == 2) or \ * (byteorder == 'big' and signalDataType == 3): # <<<<<<<<<<<<<< * return dataReadShort(bita, RecordFormat, numberOfRecords, @@ -2631,7 +2631,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":82 * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 16: # signed short + * elif signalDataType in (2, 3) and nBytes <= 2: # signed short * if (byteorder == 'little' and signalDataType == 2) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 3): * return dataReadShort(bita, RecordFormat, numberOfRecords, @@ -2662,7 +2662,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":82 * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 16: # signed short + * elif signalDataType in (2, 3) and nBytes <= 2: # signed short * if (byteorder == 'little' and signalDataType == 2) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 3): * return dataReadShort(bita, RecordFormat, numberOfRecords, @@ -2674,7 +2674,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadShort(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1, 14) and bitCount + bitOffset <=32: # unsigned int + * elif signalDataType in (0, 1, 14) and nBytes <= 4: # unsigned int */ /*else*/ { __Pyx_XDECREF(__pyx_r); @@ -2683,7 +2683,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadShort(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, 1) # <<<<<<<<<<<<<< - * elif signalDataType in (0, 1, 14) and bitCount + bitOffset <=32: # unsigned int + * elif signalDataType in (0, 1, 14) and nBytes <= 4: # unsigned int * if (byteorder == 'little' and signalDataType == 0) or \ */ __pyx_t_5 = __pyx_f_8dataRead_dataReadShort(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 87, __pyx_L1_error) @@ -2696,7 +2696,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":81 * return dataReadUShort(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 16: # signed short # <<<<<<<<<<<<<< + * elif signalDataType in (2, 3) and nBytes <= 2: # signed short # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 2) or \ * (byteorder == 'big' and signalDataType == 3): */ @@ -2705,7 +2705,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":89 * return dataReadShort(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1, 14) and bitCount + bitOffset <=32: # unsigned int # <<<<<<<<<<<<<< + * elif signalDataType in (0, 1, 14) and nBytes <= 4: # unsigned int # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): */ @@ -2725,14 +2725,14 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_2; goto __pyx_L40_bool_binop_done; } - __pyx_t_2 = (((__pyx_v_bitCount + __pyx_v_bitOffset) <= 32) != 0); + __pyx_t_2 = ((__pyx_v_nBytes <= 4) != 0); __pyx_t_3 = __pyx_t_2; __pyx_L40_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":90 * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1, 14) and bitCount + bitOffset <=32: # unsigned int + * elif signalDataType in (0, 1, 14) and nBytes <= 4: # unsigned int * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadUInt(bita, RecordFormat, numberOfRecords, @@ -2754,7 +2754,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L44_next_or:; /* "dataRead.pyx":91 - * elif signalDataType in (0, 1, 14) and bitCount + bitOffset <=32: # unsigned int + * elif signalDataType in (0, 1, 14) and nBytes <= 4: # unsigned int * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): # <<<<<<<<<<<<<< * return dataReadUInt(bita, RecordFormat, numberOfRecords, @@ -2775,7 +2775,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":90 * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1, 14) and bitCount + bitOffset <=32: # unsigned int + * elif signalDataType in (0, 1, 14) and nBytes <= 4: # unsigned int * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadUInt(bita, RecordFormat, numberOfRecords, @@ -2806,7 +2806,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":90 * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1, 14) and bitCount + bitOffset <=32: # unsigned int + * elif signalDataType in (0, 1, 14) and nBytes <= 4: # unsigned int * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadUInt(bita, RecordFormat, numberOfRecords, @@ -2818,7 +2818,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadUInt(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int + * elif signalDataType in (2, 3) and nBytes <= 4: # signed int */ /*else*/ { __Pyx_XDECREF(__pyx_r); @@ -2827,7 +2827,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadUInt(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) # <<<<<<<<<<<<<< - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int + * elif signalDataType in (2, 3) and nBytes <= 4: # signed int * if (byteorder == 'little' and signalDataType == 2) or \ */ __pyx_t_5 = __pyx_f_8dataRead_dataReadUInt(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, __pyx_v_nBytes, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 95, __pyx_L1_error) @@ -2840,7 +2840,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":89 * return dataReadShort(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1, 14) and bitCount + bitOffset <=32: # unsigned int # <<<<<<<<<<<<<< + * elif signalDataType in (0, 1, 14) and nBytes <= 4: # unsigned int # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): */ @@ -2849,7 +2849,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":97 * return dataReadUInt(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int # <<<<<<<<<<<<<< + * elif signalDataType in (2, 3) and nBytes <= 4: # signed int # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 2) or \ * (byteorder == 'big' and signalDataType == 3): */ @@ -2868,14 +2868,14 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_4; goto __pyx_L47_bool_binop_done; } - __pyx_t_4 = (((__pyx_v_bitCount + __pyx_v_bitOffset) <= 32) != 0); + __pyx_t_4 = ((__pyx_v_nBytes <= 4) != 0); __pyx_t_3 = __pyx_t_4; __pyx_L47_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":98 * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int + * elif signalDataType in (2, 3) and nBytes <= 4: # signed int * if (byteorder == 'little' and signalDataType == 2) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 3): * return dataReadInt(bita, RecordFormat, numberOfRecords, @@ -2897,7 +2897,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L51_next_or:; /* "dataRead.pyx":99 - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int + * elif signalDataType in (2, 3) and nBytes <= 4: # signed int * if (byteorder == 'little' and signalDataType == 2) or \ * (byteorder == 'big' and signalDataType == 3): # <<<<<<<<<<<<<< * return dataReadInt(bita, RecordFormat, numberOfRecords, @@ -2918,7 +2918,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":98 * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int + * elif signalDataType in (2, 3) and nBytes <= 4: # signed int * if (byteorder == 'little' and signalDataType == 2) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 3): * return dataReadInt(bita, RecordFormat, numberOfRecords, @@ -2949,7 +2949,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":98 * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int + * elif signalDataType in (2, 3) and nBytes <= 4: # signed int * if (byteorder == 'little' and signalDataType == 2) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 3): * return dataReadInt(bita, RecordFormat, numberOfRecords, @@ -2961,7 +2961,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadInt(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long + * elif signalDataType in (0, 1) and nBytes <= 8: # unsigned long long */ /*else*/ { __Pyx_XDECREF(__pyx_r); @@ -2970,7 +2970,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadInt(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) # <<<<<<<<<<<<<< - * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long + * elif signalDataType in (0, 1) and nBytes <= 8: # unsigned long long * if (byteorder == 'little' and signalDataType == 0) or \ */ __pyx_t_5 = __pyx_f_8dataRead_dataReadInt(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, __pyx_v_nBytes, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 103, __pyx_L1_error) @@ -2983,7 +2983,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":97 * return dataReadUInt(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 32: # signed int # <<<<<<<<<<<<<< + * elif signalDataType in (2, 3) and nBytes <= 4: # signed int # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 2) or \ * (byteorder == 'big' and signalDataType == 3): */ @@ -2992,7 +2992,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":105 * return dataReadInt(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long # <<<<<<<<<<<<<< + * elif signalDataType in (0, 1) and nBytes <= 8: # unsigned long long # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): */ @@ -3011,14 +3011,14 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_2; goto __pyx_L54_bool_binop_done; } - __pyx_t_2 = (((__pyx_v_bitCount + __pyx_v_bitOffset) <= 64) != 0); + __pyx_t_2 = ((__pyx_v_nBytes <= 8) != 0); __pyx_t_3 = __pyx_t_2; __pyx_L54_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":106 * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long + * elif signalDataType in (0, 1) and nBytes <= 8: # unsigned long long * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadULongLong(bita, RecordFormat, numberOfRecords, @@ -3040,7 +3040,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L58_next_or:; /* "dataRead.pyx":107 - * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long + * elif signalDataType in (0, 1) and nBytes <= 8: # unsigned long long * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): # <<<<<<<<<<<<<< * return dataReadULongLong(bita, RecordFormat, numberOfRecords, @@ -3061,7 +3061,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":106 * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long + * elif signalDataType in (0, 1) and nBytes <= 8: # unsigned long long * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadULongLong(bita, RecordFormat, numberOfRecords, @@ -3092,7 +3092,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":106 * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long + * elif signalDataType in (0, 1) and nBytes <= 8: # unsigned long long * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadULongLong(bita, RecordFormat, numberOfRecords, @@ -3104,7 +3104,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadULongLong(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long + * elif signalDataType in (2, 3) and nBytes <= 8: # signed long long */ /*else*/ { __Pyx_XDECREF(__pyx_r); @@ -3113,7 +3113,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, * else: # swap bytes * return dataReadULongLong(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) # <<<<<<<<<<<<<< - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long + * elif signalDataType in (2, 3) and nBytes <= 8: # signed long long * if (byteorder == 'little' and signalDataType == 0) or \ */ __pyx_t_5 = __pyx_f_8dataRead_dataReadULongLong(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, __pyx_v_nBytes, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 111, __pyx_L1_error) @@ -3126,7 +3126,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":105 * return dataReadInt(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (0, 1) and bitCount + bitOffset <=64: # unsigned long long # <<<<<<<<<<<<<< + * elif signalDataType in (0, 1) and nBytes <= 8: # unsigned long long # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): */ @@ -3135,7 +3135,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":113 * return dataReadULongLong(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long # <<<<<<<<<<<<<< + * elif signalDataType in (2, 3) and nBytes <= 8: # signed long long # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): */ @@ -3154,14 +3154,14 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_4; goto __pyx_L61_bool_binop_done; } - __pyx_t_4 = (((__pyx_v_bitCount + __pyx_v_bitOffset) <= 64) != 0); + __pyx_t_4 = ((__pyx_v_nBytes <= 8) != 0); __pyx_t_3 = __pyx_t_4; __pyx_L61_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":114 * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long + * elif signalDataType in (2, 3) and nBytes <= 8: # signed long long * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadLongLong(bita, RecordFormat, numberOfRecords, @@ -3183,7 +3183,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L65_next_or:; /* "dataRead.pyx":115 - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long + * elif signalDataType in (2, 3) and nBytes <= 8: # signed long long * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): # <<<<<<<<<<<<<< * return dataReadLongLong(bita, RecordFormat, numberOfRecords, @@ -3204,7 +3204,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":114 * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long + * elif signalDataType in (2, 3) and nBytes <= 8: # signed long long * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadLongLong(bita, RecordFormat, numberOfRecords, @@ -3235,7 +3235,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":114 * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long + * elif signalDataType in (2, 3) and nBytes <= 8: # signed long long * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< * (byteorder == 'big' and signalDataType == 1): * return dataReadLongLong(bita, RecordFormat, numberOfRecords, @@ -3269,7 +3269,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":113 * return dataReadULongLong(bita, RecordFormat, numberOfRecords, * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and bitCount + bitOffset <= 64: # signed long long # <<<<<<<<<<<<<< + * elif signalDataType in (2, 3) and nBytes <= 8: # signed long long # <<<<<<<<<<<<<< * if (byteorder == 'little' and signalDataType == 0) or \ * (byteorder == 'big' and signalDataType == 1): */ From 247e0cb8c1adafdb8e4974420e67a8d4b637fc96 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Mon, 1 Oct 2018 22:08:25 +0200 Subject: [PATCH 15/61] fixed bug with block naming for comments being same as channel --- mdfreader/mdf4reader.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index 8500079..03c1cc0 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -1687,7 +1687,7 @@ def write4(self, fileName=None, compression=False): unit = self.getChannelUnit(channel) if unit is not None and len(unit) > 0: blocks[nchannel]['Unit'] = pointer - unit_name = ''.join([channel, '_U']) + unit_name = '{}{}{}'.format(channel, '_U_', nchannel) blocks[unit_name] = CommentBlock() blocks[unit_name]['block_start'] = pointer blocks[unit_name].load(unit, 'TX') @@ -1699,7 +1699,7 @@ def write4(self, fileName=None, compression=False): desc = self.getChannelDesc(channel) if desc is not None and len(desc) > 0: blocks[nchannel]['Comment'] = pointer - desc_name = ''.join([channel, '_C']) + desc_name = '{}{}{}'.format(channel, '_C_', nchannel) blocks[desc_name] = CommentBlock() blocks[desc_name]['block_start'] = pointer blocks[desc_name].load(desc, 'TX') From 1c34964d4743815d3f026acb1b4e760ce2dc8aaf Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Tue, 2 Oct 2018 21:12:03 +0200 Subject: [PATCH 16/61] unique id introduction for later search by path or source --- mdfreader/channel.py | 152 ++++++++++++++++++---------------------- mdfreader/mdf.py | 9 ++- mdfreader/mdf4reader.py | 32 +++++---- mdfreader/mdfinfo4.py | 114 +++++++++++++++++++----------- 4 files changed, 170 insertions(+), 137 deletions(-) diff --git a/mdfreader/channel.py b/mdfreader/channel.py index 5bd7e5f..b3e7587 100644 --- a/mdfreader/channel.py +++ b/mdfreader/channel.py @@ -30,19 +30,21 @@ from .mdfinfo4 import ATBlock from .mdf import _bits_to_bytes, _convertName +CAN_open_offset = {'ms': 0, 'days': 4, 'minute': 2, 'hour': 3, 'day': 4, 'month': 5, 'year': 6} + class channel4(object): __slots__ = ['channelNumber', 'channelGroup', 'dataGroup', - 'type', 'name', 'VLSD_CG_Flag'] + 'type', 'name', 'VLSD_CG_Flag', 'nBytes', 'byteOffset'] """ channel class gathers all about channel structure in a record Attributes -------------- name : str Name of channel - type : str - channel type. Can be 'std', 'NestCA', - 'CAN' or 'Inv' + type : int + channel type. Can be 'standard' : 0, 'Channel Array' : 1, 'Nested Channel Array' : 2, + 'CAN' : 3 or 'Invalid' : 4 channelNumber : int channel number corresponding to mdfinfo4.info4 class channelGroup : int @@ -51,6 +53,8 @@ class channel4(object): data group number corresponding to mdfinfo4.info4 class VLSD_CG_Flag : bool flag when Channel Group VLSD is used + nBytes : int + number of bytes taken by channel at each sampling Methods ------------ @@ -81,7 +85,7 @@ class channel4(object): signal type according to specification bitCount : int number of bits used to store channel record - nBytes : int + calc_bytes : int number of bytes (1 byte = 8 bits) taken by channel record little_endian : Bool flag to inform of channel data endian @@ -137,9 +141,9 @@ def __init__(self): name : str Name of channel - type : str, default 'std' - channel type. Can be 'std', 'NestCA', - 'CAN' or 'Inv' + type : int, default 0 + Can be 'standard' : 0, 'Channel Array' : 1, 'Nested Channel Array' : 2, + 'CAN' : 3 or 'Invalid' : 4 channelNumber : int, default 0 channel number corresponding to mdfinfo4.info4 class channelGroup : int, default 0 @@ -150,11 +154,13 @@ def __init__(self): flag when Channel Group VLSD is used """ self.name = '' - self.type = 'std' + self.type = 0 self.channelNumber = 0 self.dataGroup = 0 self.channelGroup = 0 self.VLSD_CG_Flag = False + self.nBytes = 0 + self.byteOffset = 0 def __str__(self): """ channel object attributes print @@ -243,7 +249,7 @@ def signalDataType(self, info, byte_aligned=True): 13 CANopen date 14 CANopen time """ - if not self.type == 'Inv': + if not self.type == 4: # Invalid bit channel return info['CN'][self.dataGroup][self.channelGroup]\ [self.channelNumber]['cn_data_type'] else: @@ -265,9 +271,9 @@ def bitCount(self, info): ----------- integer corresponding to channel number of bits """ - if self.type in ('std', 'CA', 'NestCA'): + if self.type in (0, 1, 2): # standard or array channel return info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_bit_count'] - elif self.type == 'CAN': + elif self.type == 3: # CAN channel if self.name == 'ms': if self.signalDataType(info) == 13: return 16 @@ -277,8 +283,8 @@ def bitCount(self, info): return 16 else: return 8 - elif self.type == 'Inv': - return self.nBytes(info) * 8 + elif self.type == 4: # Invalid bit channel + return self.nBytes * 8 else: warn('Not found channel type') @@ -394,7 +400,7 @@ def isnumeric(self, info): else: return False - def nBytes(self, info): + def calc_bytes(self, info): """ calculates channel bytes number Parameters @@ -407,17 +413,17 @@ def nBytes(self, info): ----------- number of bytes integer """ - if not self.type == 'Inv': # not channel containing invalid bits - nBytes = _bits_to_bytes(info['CN'][self.dataGroup][self.channelGroup] - [self.channelNumber]['cn_bit_count'] + info['CN'][self.dataGroup][self.channelGroup] - [self.channelNumber]['cn_bit_offset'], self.isnumeric(info)) - if self.type in ('CA', 'NestCA'): + if not self.type == 4: # not channel containing invalid bit + nBytes = _bits_to_bytes(info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_bit_count'] + + info['CN'][self.dataGroup][self.channelGroup][self.channelNumber] + ['cn_bit_offset'], self.isnumeric(info)) + if self.type in (1, 2): # array channel nBytes *= self.CABlock(info)['PNd'] Block = self.CABlock(info) while 'CABlock' in Block: # nested array Block = Block['CABlock'] nBytes *= Block['PNd'] - if self.type == 'CAN': + if self.type == 3: # CAN channel if self.name == 'ms': if info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_data_type'] == 13: nBytes = 2 @@ -479,8 +485,8 @@ def numpy_format(self, info): endian, dataType : string data format """ endian = '' - if self.type == 'Inv': - dataformat = '{}V'.format(self.nBytes(info)) + if self.type == 4: # Invalid bit channel + dataformat = '{}V'.format(self.nBytes) elif info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_composition'] and \ 'CABlock' in info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]: # channel array CABlock = info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['CABlock'] @@ -501,7 +507,7 @@ def numpy_format(self, info): else: array_desc = str(array_desc) dataformat = array_desc + dataformat - elif self.type == 'CAN': + elif self.type == 3: # CAN channel if self.name == 'ms': if self.signalDataType(info) == 13: dataformat = 'u2' @@ -515,7 +521,7 @@ def numpy_format(self, info): else: # not channel array endian, dataformat = arrayformat4( info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_data_type'], - self.nBytes(info)) + self.nBytes) return endian, dataformat def dataFormat(self, info): @@ -552,21 +558,21 @@ def Format(self, info): string data C format """ signalDataType = self.signalDataType(info) - if self.type == 'std': + if self.type == 0: # standard channel if signalDataType not in (13, 14): if not self.channelType(info) == 1: # if not VSLD - endian, dataType = datatypeformat4(signalDataType, self.nBytes(info)) + endian, dataType = datatypeformat4(signalDataType, self.nBytes) else: # VLSD - endian, dataType = datatypeformat4(0, self.nBytes(info)) + endian, dataType = datatypeformat4(0, self.nBytes) return '{}{}'.format(endian, dataType) - elif self.type in ('CA', 'NestCA'): + elif self.type in (1, 2): # array channel CA = self.CABlock(info) nBytes = _bits_to_bytes(info['CN'][self.dataGroup][self.channelGroup] [self.channelNumber]['cn_bit_count'] + info['CN'][self.dataGroup][self.channelGroup] [self.channelNumber]['cn_bit_offset'], self.isnumeric(info)) endian, dataType = datatypeformat4(signalDataType, nBytes) return '{}{}{}'.format(endian, CA['PNd'], dataType) - elif self.type == 'CAN': + elif self.type == 3: # CAN channel if self.name == 'ms': if signalDataType == 13: return 'H' @@ -576,8 +582,8 @@ def Format(self, info): return 'H' else: return 'B' - elif self.type == 'Inv': - return '{}s'.format(self.nBytes(info)) + elif self.type == 4: # Invalid bit channel + return '{}s'.format(self.nBytes) else: warn('Not found channel type') @@ -596,35 +602,18 @@ def CFormat(self, info): """ return Struct(self.Format(info)) - def CANOpenOffset(self, info): + def CANOpenOffset(self): """ CANopen channel bytes offset - Parameters - ---------------- - - info : mdfinfo4.info4 class - info4 class containing all MDF Blocks - Returns ----------- integer, channel bytes offset """ - if self.name == 'ms': - return 0 - elif self.name == 'days': - return 4 - elif self.name == 'minute': - return 2 - elif self.name == 'hour': - return 3 - elif self.name == 'day': - return 4 - elif self.name == 'month': - return 5 - elif self.name == 'year': - return 6 - else: + try: + return CAN_open_offset[self.name] + except KeyError: warn('CANopen type not understood') + return None def bitOffset(self, info): """ channel data bit offset in record @@ -639,17 +628,17 @@ def bitOffset(self, info): ----------- integer, channel bit offset """ - if self.type in ('std', 'CA', 'NestCA'): + if self.type in (0, 1, 2): # standard or channel array return info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_bit_offset'] - elif self.type == 'CAN': + elif self.type == 3: # CAN channel return info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_bit_offset'] \ - + self.CANOpenOffset(info) * 8 - elif self.type == 'Inv': + + self.CANOpenOffset() * 8 + elif self.type == 4: # Invalid bit channel return 0 else: warn('Not found channel type') - def byteOffset(self, info): + def calc_byteOffset(self, info): """ channel data bytes offset in record (without record id) Parameters @@ -662,13 +651,12 @@ def byteOffset(self, info): ----------- integer, channel bytes offset """ - if self.type in ('std', 'CA', 'NestCA'): - return info['CN'][self.dataGroup][self.channelGroup]\ - [self.channelNumber]['cn_byte_offset'] - elif self.type == 'CAN': - return info['CN'][self.dataGroup][self.channelGroup]\ - [self.channelNumber]['cn_byte_offset'] + self.CANOpenOffset(info) - elif self.type == 'Inv': + if self.type in (0, 1, 2): # standard or channel array + return info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_byte_offset'] + elif self.type == 3: # CAN channel + return info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_byte_offset'] \ + + self.CANOpenOffset() + elif self.type == 4: # Invalid bit channel return info['CG'][self.dataGroup][self.channelGroup]['cg_data_bytes'] else: warn('Not found channel type') @@ -686,7 +674,7 @@ def posByteBeg(self, info): ----------- integer, channel bytes starting position """ - return self.recordIDsize(info) + self.byteOffset(info) + return self.recordIDsize(info) + self.byteOffset def posByteEnd(self, info): """ channel data bytes ending position in record @@ -701,7 +689,7 @@ def posByteEnd(self, info): ----------- integer, channel bytes ending position """ - return self.posByteBeg(info) + self.nBytes(info) + return self.posByteBeg(info) + self.nBytes def posBitBeg(self, info): """ channel data bit starting position in record @@ -771,7 +759,7 @@ def desc(self, info): ----------- channel description string """ - if not self.type == 'CAN': + if not self.type == 3: # CAN channel if self.channelNumber in info['CN'][self.dataGroup][self.channelGroup]: if 'Comment' in info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]: desc = info['CN'][self.dataGroup][self.channelGroup]\ @@ -821,21 +809,21 @@ def set(self, info, dataGroup, channelGroup, channelNumber): channel group number in mdfinfo4.info4 class channelNumber : int channel number in mdfinfo4.info4 class - recordIDsize : int - size of record ID in Bytes """ self.name = info['CN'][dataGroup][channelGroup][channelNumber]['name'] self.channelNumber = channelNumber self.dataGroup = dataGroup self.channelGroup = channelGroup - self.type = 'std' + self.type = 0 if info['CN'][dataGroup][channelGroup][channelNumber]['cn_composition'] and \ 'CABlock' in info['CN'][dataGroup][channelGroup][channelNumber]: # channel array - self.type = 'CA' + self.type = 1 Block = info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['CABlock'] if 'CABlock' in Block: # nested array - self.type = 'NestCA' + self.type = 2 + self.nBytes = self.calc_bytes(info) + self.byteOffset = self.calc_byteOffset(info) def setCANOpen(self, info, dataGroup, channelGroup, channelNumber, name): """ CANOpen channel intialisation @@ -850,17 +838,17 @@ def setCANOpen(self, info, dataGroup, channelGroup, channelNumber, name): channel group number in mdfinfo4.info4 class channelNumber : int channel number in mdfinfo4.info4 class - recordIDsize : int - size of record ID in Bytes name : str name of channel. Should be in ('ms', 'day', 'days', 'hour', 'month', 'minute', 'year') """ - self.type = 'CAN' + self.type = 3 self.name = name self.channelNumber = channelNumber self.dataGroup = dataGroup self.channelGroup = channelGroup + self.nBytes = self.calc_bytes(info) + self.byteOffset = self.calc_byteOffset(info) def setInvalidBytes(self, info, dataGroup, channelGroup, channelNumber): """ invalid_bytes channel initialisation @@ -875,16 +863,14 @@ def setInvalidBytes(self, info, dataGroup, channelGroup, channelNumber): channel group number in mdfinfo4.info4 class channelNumber : int channel number in mdfinfo4.info4 class - recordIDsize : int - size of record ID in Bytes - byte_aligned : Bool - Flag for byte alignement """ - self.type = 'Inv' + self.type = 4 self.name = 'invalid_bytes{}'.format(dataGroup) self.channelNumber = channelNumber self.dataGroup = dataGroup self.channelGroup = channelGroup + self.nBytes = self.calc_bytes(info) + self.byteOffset = self.calc_byteOffset(info) def invalid_bit(self, info): """ extracts from info4 the channels valid bits positions @@ -933,7 +919,7 @@ def bit_masking_needed(self, info): boolean True if channel needs bit masking, otherwise False """ - if not self.nBytes(info) == self.bitCount(info) / 8: + if not self.nBytes == self.bitCount(info) / 8: self.bit_masking_needed = True else: self.bit_masking_needed = False diff --git a/mdfreader/mdf.py b/mdfreader/mdf.py index 6fc9959..03324e6 100644 --- a/mdfreader/mdf.py +++ b/mdfreader/mdf.py @@ -160,7 +160,7 @@ def __init__(self, fileName=None, channelList=None, convertAfterRead=True, def add_channel(self, dataGroup, channel_name, data, master_channel, master_type=1, unit='', description='', conversion=None, - info=None, compression=False): + info=None, compression=False, id=None): """ adds channel to mdf dict. Parameters @@ -186,6 +186,11 @@ def add_channel(self, dataGroup, channel_name, data, master_channel, used for CABlock axis creation and channel conversion compression : bool flag to ask for channel data compression + id : tuple + tuple of int and str following below structure: + (data group number, channel group number, channel number), + (channel name, channel source, channel path), + (group name, group source, group path) """ if not self._noDataLoading: self[channel_name] = {} @@ -234,6 +239,8 @@ def add_channel(self, dataGroup, channel_name, data, master_channel, else: axis = CABlock['ca_axis_value'] self[channel_name]['axis'] = axis + if id is not None: + self[channel_name]['id'] = id def remove_channel(self, channel_name): """ removes channel from mdf dict. diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index 03c1cc0..ea0719e 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -682,8 +682,8 @@ def loadInfo(self, info): Channel_posBitEnd = Channel.posBitEnd(info) Channel_posBitBeg = Channel.posBitBeg(info) prev_chan = self[-2] - prev_chan_byteOffset = prev_chan.byteOffset(info) - prev_chan_nBytes = prev_chan.nBytes(info) + prev_chan_byteOffset = prev_chan.byteOffset + prev_chan_nBytes = prev_chan.nBytes prev_chan_includes_curr_chan = Channel_posBitBeg >= 8 * prev_chan_byteOffset \ and Channel_posBitEnd <= 8 * (prev_chan_byteOffset + prev_chan_nBytes) if embedding_channel is not None: @@ -691,7 +691,7 @@ def loadInfo(self, info): Channel_posBitEnd <= embedding_channel.posByteEnd(info) * 8 else: embedding_channel_includes_curr_chan = False - if Channel.byteOffset(info) >= prev_chan_byteOffset and \ + if Channel.byteOffset >= prev_chan_byteOffset and \ Channel_posBitBeg < 8 * (prev_chan_byteOffset + prev_chan_nBytes) < Channel_posBitEnd: # not byte aligned self.byte_aligned = False @@ -709,12 +709,12 @@ def loadInfo(self, info): self.recordToChannelMatching[Channel.name] = Channel.name self.numpyDataRecordFormat.append(dataFormat) self.dataRecordName.append(Channel.name) - self.recordLength += Channel.nBytes(info) + self.recordLength += Channel.nBytes if embedding_channel is None: # adding bytes self.recordToChannelMatching[Channel.name] = Channel.name self.numpyDataRecordFormat.append(dataFormat) self.dataRecordName.append(Channel.name) - self.recordLength += Channel.nBytes(info) + self.recordLength += Channel.nBytes if 'VLSD_CG' in info: # is there VLSD CG for recordID in info['VLSD_CG']: # look for VLSD CG Channel if info['VLSD_CG'][recordID]['cg_cn'] == (self.channelGroup, channelNumber): @@ -972,7 +972,7 @@ def read_channels_from_bytes(self, bita, info, channelSet=None, nrecords=None, self[chan].nativedataFormat(info), nrecords, self.CGrecordLength, self[chan].bitOffset(info), self[chan].posByteBeg(info), - self[chan].nBytes(info), array_flag) + self[chan].nBytes, array_flag) return buf else: return self.read_channels_from_bytes_fallback(bita, info, channelSet, nrecords, dtype) @@ -1030,8 +1030,8 @@ def signedInt(temp, extension): record_bit_size = self.CGrecordLength * 8 for chan in channels_indexes: signalDataType = self[chan].signalDataType(info) - nBytes = self[chan].nBytes(info) - if not self[chan].type in ('CA', 'NestCA'): + nBytes = self[chan].nBytes + if not self[chan].type in (1, 2): temp = [B[self[chan].posBitBeg(info) + record_bit_size * i: self[chan].posBitEnd(info) + record_bit_size * i] for i in range(nrecords)] @@ -1128,11 +1128,13 @@ def read4(self, fileName=None, info=None, multiProc=False, channelList=None, channelList : list of str, optional list of channel names to be read - If you use channelList, reading might be much slower but it will save you memory. Can be used to read big files + If you use channelList, reading might be much slower but it will save you memory. + Can be used to read big files convertAfterRead : bool, optional flag to convert channel after read, True by default - If you use convertAfterRead by setting it to false, all data from channels will be kept raw, no conversion applied. + If you use convertAfterRead by setting it to false, + all data from channels will be kept raw, no conversion applied. If many float are stored in file, you can gain from 3 to 4 times memory footprint To calculate value from channel, you can then use method .getChannelData() @@ -1246,7 +1248,7 @@ def returnField(obj, field): channels = [channels[self[channel][idField][2]] for channel in channelList] for chan in channels: # for each channel class if channelSet is None or chan.name in channelSet: - if not chan.type == 'Inv': # normal channel + if not chan.type == 4: # normal channel if chan.channelType(info) not in (3, 6): # not virtual channel # in case record is used for several channels if channelSet is None and not buf[recordID]['record'].hiddenBytes \ @@ -1325,7 +1327,10 @@ def returnField(obj, field): description=chan.desc(info), conversion=chan.conversion(info), info=chan.CNBlock(info), - compression=compression) + compression=compression, + id=info.unique_id(chan.dataGroup, + chan.channelGroup, + chan.channelNumber)) if chan.channelType(info) == 4: # sync channel # attach stream to be synchronised self.setChannelAttachment(chan.name, chan.attachment(info.fid, info)) @@ -1344,7 +1349,8 @@ def returnField(obj, field): unit='', description='', info=None, - compression=compression) + compression=compression, + id=None) buf[recordID].pop('data', None) del buf if minimal > 1: diff --git a/mdfreader/mdfinfo4.py b/mdfreader/mdfinfo4.py index 0b7894c..3bef66c 100644 --- a/mdfreader/mdfinfo4.py +++ b/mdfreader/mdfinfo4.py @@ -66,6 +66,14 @@ CCStruct2 = Struct('<2B3H2d') SRStruct = Struct('<4sI5Qd2B6s') +# SI Types +si_type = {0: 'OTHER', 1: 'ECU', 2: 'BUS', + 3: 'I/O', 4: 'TOOL', 5: 'USER'} +si_bus_type = {0: 'NONE', 1: 'OTHER', 2: 'CAN', 3: 'LIN', + 4: 'MOST', 5: 'FLEXRAY', 6: 'K_LINE', 7: 'ETHERNET', 8: 'USB'} +# EV cause +ev_cause = {0: 'OTHER',1: 'ERROR', 2: 'TOOL', 3: 'SCRIPT', 4: 'USER'} + chunk_size_writing = 4194304 # write by chunk of 4Mb, can be tuned for best performance @@ -635,6 +643,11 @@ def read(self, fid, pointer): comment = CommentBlock() comment.read(fid=fid, pointer=self['cg_tx_acq_name']) self['acq_name'].update(comment) + if self['cg_si_acq_source']: # comments exist + self['acq_source'] = {} + SI = SIBlock() + SI.read(fid=fid, pointer=self['cg_si_acq_source']) + self['acq_source'].update(SI) def write(self, fid): # write block header @@ -962,16 +975,10 @@ def __init__(self, fid, pointer): self['ev_md_comment']) = unpack('<5Q', fid.read(40)) self['ev_scope'] = _mdfblockread(fid, LINK, self['ev_scope_count']) # post treatment - if self['ev_cause'] == 0: - self['ev_cause'] = 'OTHER' - elif self['ev_cause'] == 1: - self['ev_cause'] == 'ERROR' - elif self['ev_cause'] == 2: - self['ev_cause'] == 'TOOL' - elif self['ev_cause'] == 3: - self['ev_cause'] == 'SCRIPT' - elif self['ev_cause'] == 4: - self['ev_cause'] == 'USER' + try: + self['ev_cause'] = ev_cause[self['ev_cause']] + except KeyError: + warn('unexpected ev cause') if self['ev_attachment_count'] > 0: self['ev_at_reference'] = \ _mdfblockread(fid, LINK, self['ev_attachment_count']) @@ -1028,36 +1035,14 @@ def read(self, fid, pointer): self['si_bus_type'], self['si_flags'], si_reserved) = SIStruct.unpack(fid.read(56)) - if self['si_type'] == 0: - self['si_type'] = 'OTHER' # unknown - elif self['si_type'] == 1: - self['si_type'] = 'ECU' - elif self['si_type'] == 2: - self['si_type'] = 'BUS' - elif self['si_type'] == 3: - self['si_type'] = 'I/O' - elif self['si_type'] == 4: - self['si_type'] = 'TOOL' - elif self['si_type'] == 5: - self['si_type'] = 'USER' - if self['si_bus_type'] == 0: - self['si_bus_type'] = 'NONE' - elif self['si_bus_type'] == 1: - self['si_bus_type'] = 'OTHER' - elif self['si_bus_type'] == 2: - self['si_bus_type'] = 'CAN' - elif self['si_bus_type'] == 3: - self['si_bus_type'] = 'LIN' - elif self['si_bus_type'] == 4: - self['si_bus_type'] = 'MOST' - elif self['si_bus_type'] == 5: - self['si_bus_type'] = 'FLEXRAY' - elif self['si_bus_type'] == 6: - self['si_bus_type'] = 'K_LINE' - elif self['si_bus_type'] == 7: - self['si_bus_type'] = 'ETHERNET' - elif self['si_bus_type'] == 8: - self['si_bus_type'] = 'USB' + try: + self['si_type'] = si_type[self['si_type']] + except KeyError: + warn('unexpected SI type') + try: + self['si_bus_type'] = si_bus_type[self['si_bus_type']] + except KeyError: + warn('unexpected SI bus type') # post treatment self['source_name'] = CommentBlock() self['source_name'].read(fid=fid, pointer=self['si_tx_name']) @@ -1535,6 +1520,8 @@ def readCNBlock(self, fid, dg, cg, channelNameList=False, minimal=0): # check for MLSD if self['CN'][dg][cg][cn]['cn_type'] == 5: MLSDChannels.append(cn) + # keep original non unique channel name + self['CN'][dg][cg][cn]['orig_name'] = self['CN'][dg][cg][cn]['name'] # check if already existing channel name self['CN'][dg][cg][cn]['name'] = self._unique(fid, self['CN'][dg][cg][cn]['name'], dg, cg, cn) if self['CN'][dg][cg][cn]['cn_type'] == 1 and PythonVersion < 3: @@ -1601,6 +1588,8 @@ def readCNBlock(self, fid, dg, cg, channelNameList=False, minimal=0): self['CN'][dg][cg][cn]['SI'] = dict() self['CN'][dg][cg][cn]['SI'].update(temp) + # keep original non unique channel name + self['CN'][dg][cg][cn]['orig_name'] = self['CN'][dg][cg][cn]['name'] # check if already existing channel name self['CN'][dg][cg][cn]['name'] = self._unique(fid, self['CN'][dg][cg][cn]['name'], dg, cg, cn) if self['CN'][dg][cg][cn]['cn_type'] == 1 and PythonVersion < 3: @@ -1698,6 +1687,8 @@ def readComposition(self, fid, dg, cg, MLSDChannels): self['CN'][dg][cg][chan] = CNBlock() self['CN'][dg][cg][chan].read(fid=fid, pointer=self['CN'][dg][cg][cn]['cn_composition']) + # keep original non unique channel name + self['CN'][dg][cg][chan]['orig_name'] = self['CN'][dg][cg][chan]['name'] # make sure channel name is unique self['CN'][dg][cg][chan]['name'] = self._unique(fid, self['CN'][dg][cg][chan]['name'], dg, cg, cn) @@ -1711,6 +1702,8 @@ def readComposition(self, fid, dg, cg, MLSDChannels): self['CN'][dg][cg][chan] = CNBlock() self['CN'][dg][cg][chan].read(fid=fid, pointer=self['CN'][dg][cg][chan - 1]['cn_cn_next']) + # keep original non unique channel name + self['CN'][dg][cg][chan]['orig_name'] = self['CN'][dg][cg][chan]['name'] # make sure channel name is unique self['CN'][dg][cg][chan]['name'] = self._unique(fid, self['CN'][dg][cg][chan]['name'], dg, cg, cn) @@ -1860,6 +1853,47 @@ def _unique(self, fid, name, dg, cg, cn): self['allChannelList'].add(name) return name + def unique_id(self, ndg, ncg, ncn): + """ generate unique id tuples + + Parameters + ---------------- + ndg : int + data group number + + ncg: int + channel group number + + ncn : int + channel number + + Returns + ----------- + tuples: (data group number, channel group number, channel number), + (channel name, channel source, channel path), + (group name, group source, group path) + """ + cn = self['CN'][ndg][ncg][ncn]['orig_name'] + try: # SI block not always existing + cs = self['CN'][ndg][ncg][ncn]['SI']['source_name'] + cp = self['CN'][ndg][ncg][ncn]['SI']['source_path'] + except KeyError: + cs = None + cp = None + try: + gn = self['CG'][ndg][ncg]['acq_name']['Comment'] + except KeyError: + gn = None + try: + gs = self['CG'][ndg][ncg]['acq_source']['source_name']['Comment'] + except KeyError: + gs = None + try: + gp = self['CG'][ndg][ncg]['acq_source']['source_path']['Comment'] + except KeyError: + gp = None + return (ndg, ncg, ncn), (cn, cs, cp), (gn, gs, gp) + def _generateDummyMDF4(info, channelList): """ computes MasterChannelList and dummy mdf dict from an info object From aae7553e067d30b1fedf216d5525ccab64c9e4b6 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Wed, 3 Oct 2018 20:08:21 +0200 Subject: [PATCH 17/61] Added getChannelName4 method to look for mdf channel name based on channel name and path or source --- mdfreader/mdf4reader.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index ea0719e..5c17310 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -1149,7 +1149,7 @@ def read4(self, fileName=None, info=None, multiProc=False, channelList=None, elif fileName is not None and self.fileName is None: self.fileName = fileName - minimal = 2 # always read minimum info + minimal = 2 # always read minimum info (2), full info (0) # set is more efficient for large number of channels (n^2 vs n*log(n)): if channelList is not None: @@ -1776,6 +1776,30 @@ def apply_invalid_bit(self, channel_name): pass # warn('no invalid data found for channel ') + def getChannelName4(self, name, path): + """finds mdf channel name from name and path + + Parameters + ---------------- + name : str + channel name + path: str + source path or name, or channel group name, source name or path + + Returns: + ----------- + channel name + + """ + for channel_name in self: + try: + (ndg, ncg, ncn), (cn, cs, cp), (gn, gs, gp) = self[channel_name]['id'] + if name == cn and path in (cs, cp) or path in (gn, gs, gp): + return channel_name, (ndg, ncg, ncn) + except KeyError: # most probably a invalid bit channel + pass + return None + def linearConv(vect, cc_val): """ apply linear conversion to data From 596f0a4dcbbce8986307b8b2a5250d850e009a0f Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Wed, 3 Oct 2018 20:13:13 +0200 Subject: [PATCH 18/61] use ObjectPath --- mdfreader/mdfinfo4.py | 218 ++++++++++++++++++++++++------------------ 1 file changed, 126 insertions(+), 92 deletions(-) diff --git a/mdfreader/mdfinfo4.py b/mdfreader/mdfinfo4.py index 3bef66c..c41fce2 100644 --- a/mdfreader/mdfinfo4.py +++ b/mdfreader/mdfinfo4.py @@ -74,6 +74,32 @@ # EV cause ev_cause = {0: 'OTHER',1: 'ERROR', 2: 'TOOL', 3: 'SCRIPT', 4: 'USER'} +# precompiled path for xmls to speed up parsing +CN_TX = objectify.ObjectPath('CNcomment.TX') +CN_names = objectify.ObjectPath('CNcomment.names') +CN_axis_monotony = objectify.ObjectPath('CNcomment.axis_monotony') +CN_raster = objectify.ObjectPath('CNcomment.raster') +CN_formula = objectify.ObjectPath('CNcomment.formula') +CN_linker_name = objectify.ObjectPath('CNcomment.linker_name') +CN_linker_address = objectify.ObjectPath('CNcomment.linker_address') +CN_address = objectify.ObjectPath('CNcomment.address') +CN_unit_TX = objectify.ObjectPath('CNunit.TX') +CC_TX = objectify.ObjectPath('CCcomment.TX') +CC_names = objectify.ObjectPath('CCcomment.names') +CC_COMPU_METHOD = objectify.ObjectPath('CCcomment.COMPU_METHOD') +CC_formula = objectify.ObjectPath('CCcomment.formula') +CC_unit_TX = objectify.ObjectPath('CCunit.TX') +SI_TX = objectify.ObjectPath('SIcomment.TX') +SI_names = objectify.ObjectPath('SIcomment.names') +SI_path = objectify.ObjectPath('SIcomment.path') +SI_bus = objectify.ObjectPath('SIcomment.bus') +SI_protocol = objectify.ObjectPath('SIcomment.protocol') +EV_TX = objectify.ObjectPath('EVcomment.TX') +EV_pre_trigger_interval = objectify.ObjectPath('EVcomment.pre_trigger_interval') +EV_post_trigger_interval = objectify.ObjectPath('EVcomment.post_trigger_interval') +EV_formula = objectify.ObjectPath('EVcomment.formula') +EV_timeout = objectify.ObjectPath('EVcomment.timeout') + chunk_size_writing = 4194304 # write by chunk of 4Mb, can be tuned for best performance @@ -233,7 +259,7 @@ def read(self, fid=None, pointer=64): if self['hd_md_comment']: # if comments exist self['Comment'] = {} comment = CommentBlock() - comment.read(fid=fid, pointer=self['hd_md_comment'], MDType='HD') + comment.readCM(fid=fid, pointer=self['hd_md_comment'], MDType=3) self['Comment'].update(comment) def write(self, fid): @@ -280,7 +306,7 @@ def read(self, fid, pointer): if self['fh_md_comment']: # comments exist self['Comment'] = {} comment = CommentBlock() - comment.read(fid=fid, pointer=self['fh_md_comment'], MDType='FH') + comment.readCM(fid=fid, pointer=self['fh_md_comment'], MDType=4) self['Comment'].update(comment) def write(self, fid): @@ -321,12 +347,12 @@ def __init__(self, fid, pointer): if self['ch_md_comment']: # comments exist self['Comment'] = {} comment= CommentBlock() - comment.read(fid=fid, pointer=self['ch_md_comment']) + comment.readCM(fid=fid, pointer=self['ch_md_comment']) self['Comment'].update(comment) if self['ch_tx_name']: # text block containing name of hierarchy level self['ch_name_level'] = {} comment = CommentBlock() - comment.read(fid=fid, pointer=self['ch_tx_name']) + comment.readCM(fid=fid, pointer=self['ch_tx_name']) self['ch_name_level'].update(comment) @@ -334,7 +360,7 @@ class CommentBlock(dict): """ reads or writes Comment block and saves in class dict """ - def read(self, **kargs): + def readCM(self, **kargs): """ reads Comment block and saves in class dict Parameters ---------- @@ -362,54 +388,81 @@ def read(self, **kargs): # removes normal 0 at end # self['Comment'] = None try: - xml_tree = objectify.fromstring(kargs['fid'].read(self['length'] - 24).rstrip(b'\x00')) + xml_string = kargs['fid'].read(self['length'] - 24).rstrip(b'\x00') + xml_tree = objectify.fromstring(xml_string) except: warn('xml metadata malformed') xml_tree = None # specific action per comment block type, # #extracts specific tags from xml if 'MDType' in kargs: - if kargs['MDType'] == 'CN': # channel comment + if kargs['MDType'] == 0: # channel comment try: - self['description'] = xml_tree.TX.text + self['description'] = CN_TX(xml_tree).text except AttributeError: warn('Could not parse CN block TX tag') try: - self['names'] = xml_tree.names.text + self['names'] = CN_names(xml_tree).text except AttributeError: pass # optional if 'minimal' in kargs and kargs['minimal'] is False: # not really used for the moment try: - self['axis_monotony'] = xml_tree.axis_monotony.text + self['axis_monotony'] = CN_axis_monotony(xml_tree).text except AttributeError: pass # optional try: - self['raster'] = xml_tree.raster.text + self['raster'] = CN_raster(xml_tree).text except AttributeError: pass # optional try: - self['formula'] = xml_tree.formula.text + self['formula'] = CN_formula(xml_tree).text except AttributeError: pass # optional try: - self['linker_name'] = xml_tree.linker_name.text + self['linker_name'] = CN_linker_name(xml_tree).text except AttributeError: pass # optional try: - self['linker_address'] = xml_tree.linker_address.text + self['linker_address'] = CN_linker_address(xml_tree).text except AttributeError: pass # optional try: - self['address'] = xml_tree.address.text + self['address'] = CN_address(xml_tree).text except AttributeError: pass # optional - elif kargs['MDType'] == 'unit': # channel comment + elif kargs['MDType'] == 1: # cn_unit channel unit + try: + self['unit'] = CN_unit_TX(xml_tree).text + except AttributeError: + warn('Could not parse unit TX tag') + elif kargs['MDType'] == 2: # CC channel unit try: - self['unit'] = xml_tree.TX + self['unit'] = CC_unit_TX(xml_tree).text except AttributeError: warn('Could not parse unit TX tag') - elif kargs['MDType'] == 'HD': # header comment + elif kargs['MDType'] == 5: # SI comments + try: + self['TX'] = SI_TX(xml_tree).text + except AttributeError: + warn('Could not parse SI block TX tag') + try: + self['names'] = SI_names(xml_tree).text + except AttributeError: + pass # optional + try: + self['path'] = SI_path(xml_tree).text + except AttributeError: + pass # optional + try: + self['bus'] = SI_bus(xml_tree).text + except AttributeError: + pass # optional + try: + self['protocol'] = SI_protocol(xml_tree).text + except AttributeError: + pass # optional + elif kargs['MDType'] == 3: # HD header comment try: self['TX'] = xml_tree.TX.text except AttributeError: @@ -424,7 +477,7 @@ def read(self, **kargs): self[tmp.e[t].attrib.values()[0]] = tmp.e[t].text except AttributeError: pass # optional - elif kargs['MDType'] == 'FH': # File History comment + elif kargs['MDType'] == 4: # FH file History comment try: self['TX'] = xml_tree.TX.text except AttributeError: @@ -445,70 +498,49 @@ def read(self, **kargs): self['user_name'] = xml_tree.user_name.text except AttributeError: pass # optional - elif kargs['MDType'] == 'SI': + elif kargs['MDType'] == 6: # CC comments try: - self['TX'] = xml_tree.TX.text - except AttributeError: - warn('Could not parse SI block TX tag') - try: - self['names'] = xml_tree.names.text - except AttributeError: - pass # optional - try: - self['path'] = xml_tree.path.text - except AttributeError: - pass # optional - try: - self['bus'] = xml_tree.bus.text - except AttributeError: - pass # optional - try: - self['protocol'] = xml_tree.protocol.text - except AttributeError: - pass # optional - elif kargs['MDType'] == 'CC': - try: - self['TX'] = xml_tree.TX.text + self['TX'] = CC_TX(xml_tree).text except AttributeError: warn('Could not parse CC block TX tag') try: - self['names'] = xml_tree.names.text + self['names'] = CC_names(xml_tree).text except AttributeError: pass # optional try: - self['COMPU_METHOD'] = xml_tree.COMPU_METHOD.text + self['COMPU_METHOD'] = CC_COMPU_METHOD(xml_tree).text except AttributeError: pass # optional try: - self['formula'] = xml_tree.formula.text + self['formula'] = CC_formula(xml_tree).text except AttributeError: pass # optional - elif kargs['MDType'] == 'EV': + elif kargs['MDType'] == 7: # EV comments try: - self['TX'] = xml_tree.TX.text + self['TX'] = EV_TX(xml_tree).text except AttributeError: warn('Could not parse EV block TX tag') try: - self['pre_trigger_interval'] = xml_tree.pre_trigger_interval.text + self['pre_trigger_interval'] = EV_pre_trigger_interval(xml_tree).text except AttributeError: pass # optional try: - self['post_trigger_interval'] = xml_tree.post_trigger_interval.text + self['post_trigger_interval'] = EV_post_trigger_interval(xml_tree).text except AttributeError: pass # optional try: - self['formula'] = xml_tree.formula.text + self['formula'] = EV_formula(xml_tree).text except AttributeError: pass # optional try: - self['timeout'] = xml_tree.timeout.text + self['timeout'] = EV_timeout(xml_tree).text except AttributeError: pass # optional else: if kargs['MDType'] is not None: warn('No recognized MDType {}'.format(kargs['MDType'])) elif self['id'] in ('##TX', b'##TX'): - if 'MDType' in kargs and kargs['MDType'] == 'CN': # channel comment + if 'MDType' in kargs and kargs['MDType'] == 0: # channel comment self['name'] = kargs['fid'].read(self['length'] - 24).rstrip(b'\x00').decode('UTF-8', 'ignore') else: self['Comment'] = kargs['fid'].read(self['length'] - 24).rstrip(b'\x00').decode('UTF-8', 'ignore') @@ -590,7 +622,7 @@ def read(self, fid, pointer): if self['dg_md_comment']: # comments exist self['Comment'] = {} comment = CommentBlock() - comment.read(fid=fid, pointer=self['dg_md_comment']) + comment.readCM(fid=fid, pointer=self['dg_md_comment']) self['Comment'].update(comment) def write(self, fid): @@ -637,16 +669,16 @@ def read(self, fid, pointer): self['cg_invalid_bytes']) = CGStruct.unpack(fid.read(104)) if self['cg_md_comment']: # comments exist self['Comment'] = CommentBlock() - self['Comment'].read(fid=fid, pointer=self['cg_md_comment']) + self['Comment'].readCM(fid=fid, pointer=self['cg_md_comment']) if self['cg_tx_acq_name']: # comments exist self['acq_name'] = {} comment = CommentBlock() - comment.read(fid=fid, pointer=self['cg_tx_acq_name']) + comment.readCM(fid=fid, pointer=self['cg_tx_acq_name']) self['acq_name'].update(comment) if self['cg_si_acq_source']: # comments exist self['acq_source'] = {} SI = SIBlock() - SI.read(fid=fid, pointer=self['cg_si_acq_source']) + SI.readSI(fid=fid, pointer=self['cg_si_acq_source']) self['acq_source'].update(SI) def write(self, fid): @@ -673,7 +705,7 @@ class CNBlock(dict): """ reads Channel block and saves in class dict """ - def read(self, **kargs): + def readCN(self, **kargs): if kargs['pointer'] != 0 and kargs['pointer'] is not None: kargs['fid'].seek(kargs['pointer']) (self['id'], @@ -727,13 +759,13 @@ def read(self, **kargs): self['cn_default_x'] = None if self['cn_md_comment']: # comments exist self['Comment'] = CommentBlock() - self['Comment'].read(fid=kargs['fid'], pointer=self['cn_md_comment'], MDType='CN', minimal=True) + self['Comment'].readCM(fid=kargs['fid'], pointer=self['cn_md_comment'], MDType=0, minimal=True) if self['cn_md_unit']: # comments exist self['unit'] = CommentBlock() - self['unit'].read(fid=kargs['fid'], pointer=self['cn_md_unit'], MDType='unit') + self['unit'].readCM(fid=kargs['fid'], pointer=self['cn_md_unit'], MDType=1) if self['cn_tx_name']: # comments exist comment = CommentBlock() - comment.read(fid=kargs['fid'], pointer=self['cn_tx_name'], MDType='CN') + comment.readCM(fid=kargs['fid'], pointer=self['cn_tx_name'], MDType=0) self['name'] = comment['name'] def write(self, fid): @@ -768,7 +800,7 @@ class CCBlock(dict): """ reads Channel Conversion block and saves in class dict """ - def read(self, fid, pointer): + def readCC(self, fid, pointer): # block header if pointer != 0 and pointer is not None: fid.seek(pointer) @@ -798,7 +830,7 @@ def read(self, fid, pointer): pointer = self['cc_ref'] self['cc_ref'] = {} cc = CommentBlock() - cc.read(fid=fid, pointer=pointer) + cc.readCM(fid=fid, pointer=pointer) self['cc_ref'].update(cc) elif self['cc_type']in (7, 8, 9, 10): # text list self['cc_ref'] = list(self['cc_ref']) @@ -809,22 +841,22 @@ def read(self, fid, pointer): # for algebraic formulae if ID in ('##TX', '##MD', b'##TX', b'##MD'): temp = CommentBlock() - temp.read(fid=fid, pointer=self['cc_ref'][i]) + temp.readCM(fid=fid, pointer=self['cc_ref'][i]) self['cc_ref'][i] = temp['Comment'] elif ID in ('##CC', b'##CC'): # for table conversion # much more complicated nesting conversions !!! cc = CCBlock() - cc.read(fid, self['cc_ref'][i]) + cc.readCC(fid, self['cc_ref'][i]) self['cc_ref'][i] = cc if self['cc_md_comment']: # comments exist self['Comment'] = CommentBlock() - self['Comment'].read(fid=fid, pointer=self['cc_md_comment'], MDType='CC') + self['Comment'].readCM(fid=fid, pointer=self['cc_md_comment'], MDType=6) if self['cc_md_unit']: # comments exist self['unit'] = CommentBlock() - self['unit'].read(fid=fid, pointer=self['cc_md_unit']) + self['unit'].readCM(fid=fid, pointer=self['cc_md_unit'], MDType=2) if self['cc_tx_name']: # comments exist self['name'] = CommentBlock() - self['name'].read(fid=fid, pointer=self['cc_tx_name']) + self['name'].readCM(fid=fid, pointer=self['cc_tx_name']) else: # no conversion self['cc_type'] = 0 @@ -936,7 +968,7 @@ def __init__(self, fid, pointer): if self['at_md_comment']: # comments exist self['Comment'] = {} comment = CommentBlock() - comment.read(fid=fid, pointer=self['at_md_comment']) + comment.readCM(fid=fid, pointer=self['at_md_comment']) self['Comment'].update(comment) @@ -987,10 +1019,10 @@ def __init__(self, fid, pointer): ATBlock(fid, self['ev_at_reference'][at]) if self['ev_md_comment']: # comments exist self['Comment'] = CommentBlock() - self['Comment'].read(fid=fid, pointer=self['ev_md_comment'], MDType='EV') + self['Comment'].readCM(fid=fid, pointer=self['ev_md_comment'], MDType=7) if self['ev_tx_name']: # comments exist self['name'] = CommentBlock() - self['name'].read(fid=fid, pointer=self['ev_tx_name']) + self['name'].readCM(fid=fid, pointer=self['ev_tx_name']) class SRBlock(dict): @@ -1020,7 +1052,7 @@ class SIBlock(dict): """ reads Source Information block and saves in class dict """ - def read(self, fid, pointer): + def readSI(self, fid, pointer): # block header if pointer != 0 and pointer is not None: fid.seek(pointer) @@ -1045,11 +1077,11 @@ def read(self, fid, pointer): warn('unexpected SI bus type') # post treatment self['source_name'] = CommentBlock() - self['source_name'].read(fid=fid, pointer=self['si_tx_name']) + self['source_name'].readCM(fid=fid, pointer=self['si_tx_name']) self['source_path'] = CommentBlock() - self['source_path'].read(fid=fid, pointer=self['si_tx_path']) + self['source_path'].readCM(fid=fid, pointer=self['si_tx_path']) self['comment'] = CommentBlock() - self['comment'].read(fid=fid, pointer=self['si_md_comment'], MDType='SI') + self['comment'].readCM(fid=fid, pointer=self['si_md_comment'], MDType=5) class DTBlock(dict): @@ -1403,7 +1435,7 @@ def readCGBlock(self, fid, dg, channelNameList=False, minimal=0): if not channelNameList and minimal: # reads Source Information Block temp = SIBlock() - temp.read(fid, self['CG'][dg][cg]['cg_si_acq_source']) + temp.readSI(fid, self['CG'][dg][cg]['cg_si_acq_source']) if temp is not None: self['CG'][dg][cg]['SI'] = dict() self['CG'][dg][cg]['SI'].update(temp) @@ -1433,7 +1465,7 @@ def readCGBlock(self, fid, dg, channelNameList=False, minimal=0): if not channelNameList and not minimal: # reads Source Information Block temp = SIBlock() - temp.read(fid, self['CG'][dg][cg]['cg_si_acq_source']) + temp.readSI(fid, self['CG'][dg][cg]['cg_si_acq_source']) if temp is not None: self['CG'][dg][cg]['SI'] = dict() self['CG'][dg][cg]['SI'].update(temp) @@ -1513,7 +1545,7 @@ def readCNBlock(self, fid, dg, cg, channelNameList=False, minimal=0): self['CC'][dg][cg][cn] = {} self['CN'][dg][cg][cn] = {} temp = CNBlock() - temp.read(fid=fid, pointer=self['CG'][dg][cg]['cg_cn_first']) + temp.readCN(fid=fid, pointer=self['CG'][dg][cg]['cg_cn_first']) if temp is not None: self['CN'][dg][cg][cn].update(temp) MLSDChannels = [] @@ -1532,12 +1564,12 @@ def readCNBlock(self, fid, dg, cg, channelNameList=False, minimal=0): if self['CG'][dg][cg]['cg_cn_first']: # Can be NIL for VLSD # reads Channel Conversion Block self['CC'][dg][cg][cn] = CCBlock() - self['CC'][dg][cg][cn].read(fid, self['CN'][dg][cg][cn]['cn_cc_conversion']) + self['CC'][dg][cg][cn].readCC(fid, self['CN'][dg][cg][cn]['cn_cc_conversion']) if not channelNameList: if not minimal: # reads Channel Source Information temp = SIBlock() - temp.read(fid, self['CN'][dg][cg][cn]['cn_si_source']) + temp.readSI(fid, self['CN'][dg][cg][cn]['cn_si_source']) if temp is not None: self['CN'][dg][cg][cn]['SI'] = dict() self['CN'][dg][cg][cn]['SI'].update(temp) @@ -1553,7 +1585,7 @@ def readCNBlock(self, fid, dg, cg, channelNameList=False, minimal=0): elif id in ('##CN', b'##CN'): self['CN'][dg][cg][cn]['CN'] = {} temp = CNBlock() - temp.read(fid=fid, pointer=self['CN'][dg][cg][cn]['cn_composition']) + temp.readCN(fid=fid, pointer=self['CN'][dg][cg][cn]['cn_composition']) self['CN'][dg][cg][cn]['CN'].update(temp) else: raise('unknown channel composition') @@ -1571,19 +1603,19 @@ def readCNBlock(self, fid, dg, cg, channelNameList=False, minimal=0): cn = cn + 1 self['CN'][dg][cg][cn] = {} temp = CNBlock() - temp.read(fid=fid, pointer=self['CN'][dg][cg][cn - 1]['cn_cn_next']) + temp.readCN(fid=fid, pointer=self['CN'][dg][cg][cn - 1]['cn_cn_next']) self['CN'][dg][cg][cn].update(temp) # check for MLSD if self['CN'][dg][cg][cn]['cn_type'] == 5: MLSDChannels.append(cn) # reads Channel Conversion Block self['CC'][dg][cg][cn] = CCBlock() - self['CC'][dg][cg][cn].read(fid, self['CN'][dg][cg][cn]['cn_cc_conversion']) + self['CC'][dg][cg][cn].readCC(fid, self['CN'][dg][cg][cn]['cn_cc_conversion']) if not channelNameList: if not minimal: # reads Channel Source Information temp = SIBlock() - temp.read(fid, self['CN'][dg][cg][cn]['cn_si_source']) + temp.readSI(fid, self['CN'][dg][cg][cn]['cn_si_source']) if temp is not None: self['CN'][dg][cg][cn]['SI'] = dict() self['CN'][dg][cg][cn]['SI'].update(temp) @@ -1608,7 +1640,7 @@ def readCNBlock(self, fid, dg, cg, channelNameList=False, minimal=0): elif id in ('##CN', b'##CN'): self['CN'][dg][cg][cn]['CN'] = {} temp = CNBlock() - temp.read(fid=fid, pointer=self['CN'][dg][cg][cn]['cn_composition']) + temp.readCN(fid=fid, pointer=self['CN'][dg][cg][cn]['cn_composition']) self['CN'][dg][cg][cn]['CN'].update(temp) else: raise('unknown channel composition') @@ -1685,7 +1717,7 @@ def readComposition(self, fid, dg, cg, MLSDChannels): ID = unpack('4s', fid.read(4))[0] if ID in ('##CN', b'##CN'): # Structures self['CN'][dg][cg][chan] = CNBlock() - self['CN'][dg][cg][chan].read(fid=fid, + self['CN'][dg][cg][chan].readCN(fid=fid, pointer=self['CN'][dg][cg][cn]['cn_composition']) # keep original non unique channel name self['CN'][dg][cg][chan]['orig_name'] = self['CN'][dg][cg][chan]['name'] @@ -1693,14 +1725,14 @@ def readComposition(self, fid, dg, cg, MLSDChannels): self['CN'][dg][cg][chan]['name'] = self._unique(fid, self['CN'][dg][cg][chan]['name'], dg, cg, cn) self['CC'][dg][cg][chan] = CCBlock() - self['CC'][dg][cg][chan].read(fid, self['CN'][dg][cg][chan]['cn_cc_conversion']) + self['CC'][dg][cg][chan].readCC(fid, self['CN'][dg][cg][chan]['cn_cc_conversion']) if self['CN'][dg][cg][chan]['cn_type'] == 5: MLSDChannels.append(chan) while self['CN'][dg][cg][chan]['cn_cn_next']: chan += 1 self['CN'][dg][cg][chan] = CNBlock() - self['CN'][dg][cg][chan].read(fid=fid, + self['CN'][dg][cg][chan].readCN(fid=fid, pointer=self['CN'][dg][cg][chan - 1]['cn_cn_next']) # keep original non unique channel name self['CN'][dg][cg][chan]['orig_name'] = self['CN'][dg][cg][chan]['name'] @@ -1708,7 +1740,7 @@ def readComposition(self, fid, dg, cg, MLSDChannels): self['CN'][dg][cg][chan]['name'] = self._unique(fid, self['CN'][dg][cg][chan]['name'], dg, cg, cn) self['CC'][dg][cg][chan] = CCBlock() - self['CC'][dg][cg][chan].read(fid, self['CN'][dg][cg][chan]['cn_cc_conversion']) + self['CC'][dg][cg][chan].readCC(fid, self['CN'][dg][cg][chan]['cn_cc_conversion']) if self['CN'][dg][cg][chan]['cn_type'] == 5: MLSDChannels.append(chan) # makes the channel virtual @@ -1830,7 +1862,7 @@ def _unique(self, fid, name, dg, cg, cn): if name in self['ChannelNamesByDG'][dg]: # for unsorted data if self['CN'][dg][cg][cn]['cn_si_source']: temp = SIBlock() - temp.read(fid, self['CN'][dg][cg][cn]['cn_si_source']) + temp.readSI(fid, self['CN'][dg][cg][cn]['cn_si_source']) if temp['si_tx_name'] > 0: source_name = temp['source_name']['Comment'] else: @@ -1841,7 +1873,7 @@ def _unique(self, fid, name, dg, cg, cn): elif name in self['allChannelList']: # for sorted data if self['CN'][dg][cg][cn]['cn_si_source']: temp = SIBlock() - temp.read(fid, self['CN'][dg][cg][cn]['cn_si_source']) + temp.readSI(fid, self['CN'][dg][cg][cn]['cn_si_source']) if temp['si_tx_name'] > 0: source_name = temp['source_name']['Comment'] else: @@ -1875,10 +1907,12 @@ def unique_id(self, ndg, ncg, ncn): """ cn = self['CN'][ndg][ncg][ncn]['orig_name'] try: # SI block not always existing - cs = self['CN'][ndg][ncg][ncn]['SI']['source_name'] - cp = self['CN'][ndg][ncg][ncn]['SI']['source_path'] + cs = self['CN'][ndg][ncg][ncn]['SI']['source_name']['Comment'] except KeyError: cs = None + try: + cp = self['CN'][ndg][ncg][ncn]['SI']['source_path']['Comment'] + except KeyError: cp = None try: gn = self['CG'][ndg][ncg]['acq_name']['Comment'] From 062cad108c6e171ca08a6edcdf570b4e7703949f Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Sat, 6 Oct 2018 10:14:28 +0200 Subject: [PATCH 19/61] introduced metadata input argument to tune metadata reading --- mdfreader/mdf.py | 5 +++-- mdfreader/mdf3reader.py | 17 ++++++++++++++--- mdfreader/mdf4reader.py | 18 +++++++++++++----- mdfreader/mdfreader.py | 27 ++++++++++++++++++--------- 4 files changed, 48 insertions(+), 19 deletions(-) diff --git a/mdfreader/mdf.py b/mdfreader/mdf.py index 03324e6..0705d51 100644 --- a/mdfreader/mdf.py +++ b/mdfreader/mdf.py @@ -97,7 +97,7 @@ class mdf_skeleton(dict): def __init__(self, fileName=None, channelList=None, convertAfterRead=True, filterChannelNames=False, noDataLoading=False, - compression=False, convertTables=False): + compression=False, convertTables=False, metadata=2): """ mdf_skeleton class constructor. Parameters @@ -156,7 +156,8 @@ def __init__(self, fileName=None, channelList=None, convertAfterRead=True, convertAfterRead=convertAfterRead, filterChannelNames=filterChannelNames, noDataLoading=noDataLoading, - compression=compression) + compression=compression, + metadata=metadata) def add_channel(self, dataGroup, channel_name, data, master_channel, master_type=1, unit='', description='', conversion=None, diff --git a/mdfreader/mdf3reader.py b/mdfreader/mdf3reader.py index 9750402..f33ede7 100644 --- a/mdfreader/mdf3reader.py +++ b/mdfreader/mdf3reader.py @@ -824,7 +824,8 @@ class mdf3(mdf_skeleton): """ def read3(self, fileName=None, info=None, multiProc=False, channelList=None, - convertAfterRead=True, filterChannelNames=False, compression=False): + convertAfterRead=True, filterChannelNames=False, compression=False + , metadata=2): """ Reads mdf 3.x file data and stores it in dict Parameters @@ -850,8 +851,18 @@ def read3(self, fileName=None, info=None, multiProc=False, channelList=None, If many float are stored in file, you can gain from 3 to 4 times memory footprint To calculate value from channel, you can then use method .getChannelData() + filterChannelNames : bool, optional + flag to filter long channel names from its module names separated by '.' + compression : bool, optional - falg to activate data compression with blosc + flag to activate data compression with blosc + + metadata: int, optional, default = 2 + Reading metadata has impact on performance, especially for mdf 4.x using xml. + 2: minimal metadata reading (mostly channel blocks) + 1: used for noDataLoading + 0: all metadata reading + """ self.multiProc = multiProc if platform == 'win32': @@ -862,7 +873,7 @@ def read3(self, fileName=None, info=None, multiProc=False, channelList=None, elif fileName is not None and self.fileName is None: self.fileName = fileName - minimal = 2 # always reads minimum info by default + minimal = metadata # always reads minimum info by default if channelList is None: channelSetFile = None diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index 5c17310..157bf04 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -1112,7 +1112,7 @@ class mdf4(mdf_skeleton): """ def read4(self, fileName=None, info=None, multiProc=False, channelList=None, - convertAfterRead=True, filterChannelNames=False, compression=False): + convertAfterRead=True, compression=False, metadata=2): """ Reads mdf 4.x file data and stores it in dict Parameters @@ -1139,7 +1139,14 @@ def read4(self, fileName=None, info=None, multiProc=False, channelList=None, To calculate value from channel, you can then use method .getChannelData() compression : bool, optional - falg to activate data compression with blosc + flag to activate data compression with blosc + + metadata: int, optional, default = 2 + Reading metadata has impact on performance, especially for mdf 4.x using xml. + 2: minimal metadata reading (mostly channel blocks) + 1: used for noDataLoading + 0: all metadata reading, including Source Information, Attachment, etc.. + """ self.multiProc = multiProc @@ -1149,7 +1156,7 @@ def read4(self, fileName=None, info=None, multiProc=False, channelList=None, elif fileName is not None and self.fileName is None: self.fileName = fileName - minimal = 2 # always read minimum info (2), full info (0) + minimal = metadata # always read minimum info (2), full info (0) # set is more efficient for large number of channels (n^2 vs n*log(n)): if channelList is not None: @@ -1791,14 +1798,15 @@ def getChannelName4(self, name, path): channel name """ + output = [] for channel_name in self: try: (ndg, ncg, ncn), (cn, cs, cp), (gn, gs, gp) = self[channel_name]['id'] if name == cn and path in (cs, cp) or path in (gn, gs, gp): - return channel_name, (ndg, ncg, ncn) + output.append(channel_name, (ndg, ncg, ncn)) except KeyError: # most probably a invalid bit channel pass - return None + return output def linearConv(vect, cc_val): diff --git a/mdfreader/mdfreader.py b/mdfreader/mdfreader.py index 1c01450..020d548 100644 --- a/mdfreader/mdfreader.py +++ b/mdfreader/mdfreader.py @@ -262,7 +262,8 @@ class mdf(mdf3, mdf4): Methods ------------ - read( fileName = None, multiProc = False, channelList=None, convertAfterRead=True, filterChannelNames=False, noDataLoading=False, compression=False) + read( fileName = None, multiProc = False, channelList=None, convertAfterRead=True, filterChannelNames=False, + noDataLoading=False, compression=False) reads mdf file version 3.x and 4.x write( fileName=None ) writes simple mdf file @@ -331,7 +332,7 @@ class mdf(mdf3, mdf4): def read(self, fileName=None, multiProc=False, channelList=None, convertAfterRead=True, filterChannelNames=False, - noDataLoading=False, compression=False): + noDataLoading=False, compression=False, metadata=2): """ reads mdf file version 3.x and 4.x Parameters @@ -344,12 +345,13 @@ def read(self, fileName=None, multiProc=False, channelList=None, channelList : list of str, optional list of channel names to be read - If you use channelList, reading might be much slower but it will save you memory. Can be used to read big files + If you use channelList, reading might be much slower but it will save you memory. + Can be used to read big files convertAfterRead : bool, optional flag to convert channel after read, True by default - If you use convertAfterRead by setting it to false, all data from channels will be kept raw, no conversion applied. - If many float are stored in file, you can gain from 3 to 4 times memory footprint + If you use convertAfterRead by setting it to false, all data from channels will be kept raw, + no conversion applied. If many float are stored in file, you can gain from 3 to 4 times memory footprint To calculate value from channel, you can then use method .getChannelData() filterChannelNames : bool, optional @@ -364,15 +366,22 @@ def read(self, fileName=None, multiProc=False, channelList=None, if compression = 'blosc', uses blosc for compression Choice given, efficiency depends of data + metadata: int, optional, default = 2 + Reading metadata has impact on performance, especially for mdf 4.x using xml. + 2: minimal metadata reading (mostly channel blocks) + 1: used for noDataLoading + 0: all metadata reading, including Source Information, Attachment, etc.. + Notes -------- - If you keep convertAfterRead to true, you can set attribute mdf.multiProc to activate channel conversion in multiprocessing. - Gain in reading time can be around 30% if file is big and using a lot of float channels + If you keep convertAfterRead to true, you can set attribute mdf.multiProc to activate channel conversion + in multiprocessing. Gain in reading time can be around 30% if file is big and using a lot of float channels Warning: ------------ MultiProc use should be avoided when reading several files in a batch, it is not thread safe. - You should better multi process instances of mdf rather than using multiproc in mdf class (see implementation of mdfconverter) + You should better multi process instances of mdf rather than using multiproc in mdf class + (see implementation of mdfconverter) """ if self.fileName is None or fileName is not None: self.fileName = fileName @@ -397,7 +406,7 @@ def read(self, fileName=None, multiProc=False, channelList=None, else: # MDF version 4.x if not noDataLoading: self.read4(self.fileName, None, multiProc, channelList, - convertAfterRead, filterChannelNames, compression) + convertAfterRead, compression, metadata) else: # populate minimum mdf structure self._noDataLoading = True self.info = info4(None, fid=self.fid, minimal=1) From d7e02de5e47000eda15c56c49184435a2c9448a9 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Sat, 6 Oct 2018 22:54:39 +0200 Subject: [PATCH 20/61] improved documentation --- docs/conf.py | 12 ++++++++---- docs/index.rst | 4 ++-- docs/mdfreader.pdf | Bin 269758 -> 234333 bytes mdfreader/channel.py | 11 +---------- mdfreader/mdf.py | 16 +++++++--------- mdfreader/mdf3reader.py | 18 +++++------------- mdfreader/mdf4reader.py | 11 +++++------ mdfreader/mdfinfo3.py | 9 ++++----- mdfreader/mdfinfo4.py | 16 +++++----------- mdfreader/mdfreader.py | 34 +++++++++++----------------------- 10 files changed, 48 insertions(+), 83 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 2bc2914..4d67959 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -25,7 +25,8 @@ # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.autosummary', 'numpydoc', 'rst2pdf.pdfbuilder'] +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon', 'numpydoc', 'sphinx.ext.intersphinx', + 'sphinx.ext.coverage'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -41,16 +42,16 @@ # General information about the project. project = u'mdfreader' -copyright = u'2015, Aymeric Rateau' +copyright = u'2018, Aymeric Rateau' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '2.7.5' +version = '2.8' # The full version, including alpha/beta/rc tags. -release = '2.7.5' +release = '2.8' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -247,3 +248,6 @@ # rst2pdf - name of the generated pdf # Sample rst2pdf doc - title of the pdf # Your Name - author name in the pdf + +napoleon_numpy_docstring = True +numpydoc_show_class_members = False \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index c12d271..3092b92 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -11,10 +11,10 @@ Contents: .. toctree:: :maxdepth: 3 - mdf/index - mdfreader/index + mdf/index + mdf3reader/index mdfinfo3/index diff --git a/docs/mdfreader.pdf b/docs/mdfreader.pdf index 35365a042f3a069890e54ed33ec390078f8e8741..264377014e090ef0bc8d805dd24c0d3ed3977a3f 100644 GIT binary patch delta 226135 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%0Dx9*DV>=>0a)J9lNpBVzfoT(ypUv4PGptG9 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 z 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 delta 260520 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

SazQ`I34)P;fAPweY45Nu!kW^ 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

3Yjge?3!P^dI9Dxmg9B8Co7 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%0Dt6X{U~Z2^UaY4IPG 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 diff --git a/mdfreader/channel.py b/mdfreader/channel.py index b3e7587..d7f0778 100644 --- a/mdfreader/channel.py +++ b/mdfreader/channel.py @@ -1,26 +1,17 @@ # -*- coding: utf-8 -*- """ Measured Data Format file reader module. -Platform and python version ----------------------------------------- -With Unix and Windows for python 2.7 and 3.4+ - :Author: `Aymeric Rateau `__ Created on Wed Oct 04 21:13:28 2017 -Dependencies -------------------- -- Python >2.6, >3.4 -- Numpy >1.6 - Attributes -------------- PythonVersion : float Python version currently running, needed for compatibility of both python 2.6+ and 3.4+ -channel module +channel -------------------------- """ diff --git a/mdfreader/mdf.py b/mdfreader/mdf.py index 0705d51..fbb3740 100644 --- a/mdfreader/mdf.py +++ b/mdfreader/mdf.py @@ -3,18 +3,16 @@ Created on Thu Sept 24 2015 -Platform and python version ----------------------------------------- -With Unix and Windows for python 2.6+ and 3.2+ - :Author: `Aymeric Rateau `__ + Dependencies ------------------- - Python >2.6, >3.2 - Numpy >1.6 -mdf module + +mdf -------------------------- """ from __future__ import absolute_import # for consistency between python 2 and 3 @@ -25,7 +23,7 @@ from random import choice from string import ascii_letters from sys import version_info -from collections import OrderedDict,defaultdict +from collections import OrderedDict, defaultdict from warnings import warn from numpy import array_repr, set_printoptions, recarray, fromstring try: @@ -644,7 +642,7 @@ def copy(self): Returns: ------------ - mdf_skeleton class instance + mdf_skeleton: class instance copy of a mdf_skeleton class """ yop = mdf_skeleton() @@ -666,12 +664,12 @@ def _open_MDF(fileName): Parameters ----------- filename : str - filename string + filename string Returns: -------- fid - file identifier + file identifier """ try: diff --git a/mdfreader/mdf3reader.py b/mdfreader/mdf3reader.py index f33ede7..5906b0e 100644 --- a/mdfreader/mdf3reader.py +++ b/mdfreader/mdf3reader.py @@ -1,19 +1,10 @@ # -*- coding: utf-8 -*- """ Measured Data Format file reader module for version 3.x -Platform and python version ----------------------------------------- -With Unix and Windows for python 2.6+ and 3.2+ - :Author: `Aymeric Rateau `__ Created on Sun Oct 10 12:57:28 2010 -Dependencies -------------------- -- Python >2.6, >3.2 -- Numpy >1.6 -- Sympy to convert channels with formula Attributes -------------- @@ -21,7 +12,8 @@ Python version currently running, needed for compatibility of both python 2.6+ and 3.2+ -mdf3reader module + +mdf3reader -------------------------- """ from __future__ import absolute_import # for consistency between python 2 and 3 @@ -689,7 +681,7 @@ def addRecord(self, record): Parameters ---------------- - record class + record: class channel group definition listing record channel classes """ self[record.recordID] = {} @@ -727,7 +719,7 @@ def loadSorted(self, record, nameList=None): # reads sorted data Parameters ---------------- - record class + record: class channel group definition listing record channel classes channelSet : set of str, optional list of channel names @@ -743,7 +735,7 @@ def loadUnSorted(self, nameList=None): Parameters ---------------- - record class + record: class channel group definition listing record channel classes channelSet : set of str, optional list of channel names diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index 157bf04..81e7de8 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -1,14 +1,11 @@ # -*- coding: utf-8 -*- """ Measured Data Format file reader module for version 4.x. -Platform and python version ----------------------------------------- -With Unix and Windows for python 2.6+ and 3.2+ - :Author: `Aymeric Rateau `__ Created on Thu Dec 10 12:57:28 2013 + Dependencies ------------------- - Python >2.6, >3.2 @@ -17,13 +14,15 @@ - Sympy to convert channels with formula if needed - zlib to uncompress data block if needed + Attributes -------------- PythonVersion : float Python version currently running, needed for compatibility of both python 2.6+ and 3.2+ -mdf4reader module + +mdf4reader -------------------------- """ @@ -279,7 +278,7 @@ def addRecord(self, record): Parameters ---------------- - record class + record: class channel group definition listing record channel classes """ self[record.recordID] = {} diff --git a/mdfreader/mdfinfo3.py b/mdfreader/mdfinfo3.py index 3e2691e..c572f9d 100644 --- a/mdfreader/mdfinfo3.py +++ b/mdfreader/mdfinfo3.py @@ -3,23 +3,22 @@ Created on Thu Dec 9 12:57:28 2014 -Platform and python version ----------------------------------------- -With Unix and Windows for python 2.6+ and 3.2+ - :Author: `Aymeric Rateau `__ + Dependencies ------------------- - Python >2.6, >3.2 - Numpy >1.6 + Attributes -------------- PythonVersion : float Python version currently running, needed for compatibility of both python 2.6+ and 3.2+ -mdfinfo3 module + +mdfinfo3 -------------------------- """ from __future__ import absolute_import # for consistency between python 2 and 3 diff --git a/mdfreader/mdfinfo4.py b/mdfreader/mdfinfo4.py index c41fce2..d848977 100644 --- a/mdfreader/mdfinfo4.py +++ b/mdfreader/mdfinfo4.py @@ -1,26 +1,18 @@ # -*- coding: utf-8 -*- """ Measured Data Format blocks paser for version 4.x -Platform and python version ----------------------------------------- -With Unix and Windows for python 2.6+ and 3.2+ - Created on Sun Dec 15 12:57:28 2013 :Author: `Aymeric Rateau `__ -Dependencies -------------------- -- Python >2.6, >3.2 -- Numpy >1.6 - Attributes -------------- PythonVersion : float Python version currently running, needed for compatibility of both python 2.6+ and 3.2+ -mdfinfo4 module + +mdfinfo4 -------------------------- """ from __future__ import absolute_import # for consistency between python 2 and 3 @@ -362,9 +354,11 @@ class CommentBlock(dict): def readCM(self, **kargs): """ reads Comment block and saves in class dict + Parameters ---------- - fid: file identifier + fid: + file identifier pointer: int position in file MDType: str diff --git a/mdfreader/mdfreader.py b/mdfreader/mdfreader.py index 020d548..4d1ecd7 100644 --- a/mdfreader/mdfreader.py +++ b/mdfreader/mdfreader.py @@ -28,7 +28,8 @@ PythonVersion : float Python version currently running, needed for compatibility of both python 2.6+ and 3.2+ -mdfreader module + +mdfreader -------------------------- """ from __future__ import absolute_import # for consistency between python 2 and 3 @@ -263,7 +264,7 @@ class mdf(mdf3, mdf4): Methods ------------ read( fileName = None, multiProc = False, channelList=None, convertAfterRead=True, filterChannelNames=False, - noDataLoading=False, compression=False) + noDataLoading=False, compression=False) reads mdf file version 3.x and 4.x write( fileName=None ) writes simple mdf file @@ -844,9 +845,9 @@ def exportToNetCDF(self, filename=None, sampling=None): sampling : float, optional sampling interval. - Dependency - ----------------- - scipy + Notes + -------- + Dependency: scipy """ try: from scipy.io import netcdf @@ -945,14 +946,11 @@ def exportToHDF5(self, filename=None, sampling=None, compression=None, compressi HDF5 gzip compression level, 0-9. Only valid if gzip compression is used. Level 4 (default) recommended for best balance between compression and time. - Dependency - ------------------ - h5py - Notes -------- The maximum attributes will be stored Data structure will be similar has it is in masterChannelList attribute + Dependency: h5py """ # try: @@ -1055,16 +1053,13 @@ def exportToMatlab(self, filename=None): filename : str, optional file name. If no name defined, it will use original mdf name and path - Dependency - ------------------ - scipy - Notes -------- This method will dump all data into Matlab file but you will loose below information: - unit and descriptions of channel - data structure, what is corresponding master channel to a channel. - Channels might have then different lengths + Channels might have then different lengths + Dependency: scipy """ # export class data struture into .mat file try: @@ -1097,16 +1092,12 @@ def exportToExcel(self, filename=None): filename : str, optional file name. If no name defined, it will use original mdf name and path - Dependencies - -------------------- - xlwt for python 2.6+ - xlwt3 for python 3.2+ - Notes -------- xlwt is not fast even for small files, consider other binary formats like HDF5 or Matlab If there are more than 256 channels, data will be saved over different worksheets Also Excel 2003 is becoming rare these days, prefer using exportToXlsx + Dependencies: xlwt for python 2.6+, xlwt3 for python 3.2+ """ try: if PythonVersion < 3: @@ -1174,13 +1165,10 @@ def exportToXlsx(self, filename=None): filename : str, optional file name. If no name defined, it will use original mdf name and path - Dependency - ----------------- - openpyxl - Notes -------- It is recommended to export resampled data for performances + Dependency: openpyxl """ try: import openpyxl From aea0435901735f0dbcd52b8e8ad5ea25b9de06d8 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Sun, 7 Oct 2018 20:03:49 +0200 Subject: [PATCH 21/61] added getChannelName4 example --- README.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 842d1dc..14f4fa2 100644 --- a/README.md +++ b/README.md @@ -87,11 +87,16 @@ Command example in ipython: # you can print file content in ipython with a simple: yop # alternatively, for max speed and smaller memory footprint, read only few channels - yop=mdfreader.mdf('NameOfFile',channelList=['channel1', 'channel2'],convertAfterRead=False) + yop=mdfreader.mdf('NameOfFile', channelList=['channel1', 'channel2'], convertAfterRead=False) # also possible to keep data compressed for small memory footprint, using Blosc module - yop=mdfreader.mdf('NameOfFile',compression=True) + yop=mdfreader.mdf('NameOfFile', compression=True) # for interactive file exploration, possible to read the file but not its data to save memory - yop=mdfreader.mdf('NameOfFile',noDataLoading=True) # channel data will be loaded from file if needed + yop=mdfreader.mdf('NameOfFile', noDataLoading=True) # channel data will be loaded from file if needed + # parsing xml metadata from mdf4.x for many channels can take more than just reading data. + # By using metadata argument, you can reduce to minimum metadata reading (no source information, attachment, etc.) + yop=mdfreader.mdf('NameOfFile', metadata=0) # 0: full, 2: minimal + # only for mdf4.x, you can look for a channel name and its corresponding mdf key that can can have been recorded by different sources + yop.getChannelName4('channelName', 'source path or name') # to yield one channel and keep its content in mdf object yop.getChannel('channelName') # to yield one channel numpy array @@ -128,7 +133,7 @@ Command example in ipython: yop.keepChannels({'channel1','channel2','channel3'}) # merge 2 files yop2=mdfreader.mdf('NameOfFile_2') - yop=mergeMDF(yop2) + yop.mergeMDF(yop2) # can write mdf file after modifications or creation from scratch # write4 and write3 also allow to convert file versions yop.write('NewNameOfFile') # write in same version as original file after modifications From 8c8a95cf61766b1eb69466e99173c545959f277e Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Tue, 9 Oct 2018 23:05:59 +0200 Subject: [PATCH 22/61] corrected typo --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 14f4fa2..cba0b0a 100644 --- a/README.md +++ b/README.md @@ -93,10 +93,10 @@ Command example in ipython: # for interactive file exploration, possible to read the file but not its data to save memory yop=mdfreader.mdf('NameOfFile', noDataLoading=True) # channel data will be loaded from file if needed # parsing xml metadata from mdf4.x for many channels can take more than just reading data. - # By using metadata argument, you can reduce to minimum metadata reading (no source information, attachment, etc.) + # You can reduce to minimum metadata reading with below argument (no source information, attachment, etc.) yop=mdfreader.mdf('NameOfFile', metadata=0) # 0: full, 2: minimal - # only for mdf4.x, you can look for a channel name and its corresponding mdf key that can can have been recorded by different sources - yop.getChannelName4('channelName', 'source path or name') + # only for mdf4.x, you can search for the mdf key of a channel name that can have been recorded by different sources + yop.getChannelName4('channelName', 'source path or name') # returns list of mdf keys # to yield one channel and keep its content in mdf object yop.getChannel('channelName') # to yield one channel numpy array From 0895a77c733f0b9ddf167dfd3cbceb24a66ad732 Mon Sep 17 00:00:00 2001 From: Daniel Hrisca Date: Fri, 12 Oct 2018 10:08:51 +0300 Subject: [PATCH 23/61] fix numpy includes --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index fd2ab68..b08f8f0 100644 --- a/setup.py +++ b/setup.py @@ -108,7 +108,7 @@ setup(name=name, version=version, description=description, long_description=long_description, url=url, author=author, author_email=author_email, license=license, classifiers=classifiers, keywords=keywords, packages=packages, install_requires=install_requires, extras_require=extras_require, - entry_points=entry_points, ext_modules=ext_modules) + entry_points=entry_points, ext_modules=ext_modules, include_dirs=[numpy.get_include()]) except: # without Cython import sys print("Unexpected error:", sys.exc_info()) @@ -117,6 +117,6 @@ setup(name=name, version=version, description=description, long_description=long_description, url=url, author=author, author_email=author_email, license=license, classifiers=classifiers, keywords=keywords, packages=packages, install_requires=install_requires, extras_require=extras_require, - entry_points=entry_points) + entry_points=entry_points, include_dirs=[numpy.get_include()]) warn('It is strongly advised to install Cython along with compilation environment ' 'for performance and robustness purpose') From a16ed6924a5d5de82e2071d61895b7256e36d3d5 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Mon, 15 Oct 2018 21:50:59 +0200 Subject: [PATCH 24/61] fixed bug in __str__ with nested list print --- mdfreader/mdf.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mdfreader/mdf.py b/mdfreader/mdf.py index fbb3740..81a8fea 100644 --- a/mdfreader/mdf.py +++ b/mdfreader/mdf.py @@ -604,14 +604,14 @@ def __str__(self): output.append('') for m in self.file_metadata.keys(): if self.file_metadata[m] is not None: - output.append([m, ' : {}\n'.format(self.file_metadata[m])]) + output.append('{} : {}\n'.format(m, self.file_metadata[m])) if not self._pandasframe: output.append('\nchannels listed by data groups:\n') for d in self.masterChannelList.keys(): if d is not None: - output.append([d, '\n']) + output.append('{}\n'.format(d)) for c in self.masterChannelList[d]: - output.append([' ', c, ' : ']) + output.append(' {} : '.format(c)) desc = self.getChannelDesc(c) if desc is not None: try: @@ -626,8 +626,8 @@ def __str__(self): precision=3, suppress_small=True)) unit = self.getChannelUnit(c) if unit is not None: - output.append([' ', unit, '\n']) - return output + output.append(' {}\n'.format(unit)) + return ''.join(output) else: set_option('max_rows', 3) set_option('expand_frame_repr', True) @@ -635,7 +635,7 @@ def __str__(self): for master in self.masterGroups: output.append(master) output.append(str(self[master])) - return output + return ''.join(output) def copy(self): """copy a mdf class From 0e041947a1914b3a1bcac7d1790ff98c1ace42fd Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Tue, 16 Oct 2018 22:10:17 +0200 Subject: [PATCH 25/61] bug for full int32, nBytes was not correct --- dataRead.c | 45 ++++++++++++++++----------------------------- 1 file changed, 16 insertions(+), 29 deletions(-) diff --git a/dataRead.c b/dataRead.c index d9a8f16..8959513 100644 --- a/dataRead.c +++ b/dataRead.c @@ -1,18 +1,5 @@ /* Generated by Cython 0.28.4 */ -/* BEGIN: Cython Metadata -{ - "distutils": { - "depends": [], - "name": "dataRead", - "sources": [ - "dataRead.pyx" - ] - }, - "module_name": "dataRead" -} -END: Cython Metadata */ - #define PY_SSIZE_T_CLEAN #include "Python.h" #ifndef Py_PYTHON_H @@ -5645,7 +5632,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ * cdef char temp3[3] * if bitCount == 32: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) + * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) */ __pyx_t_6 = ((__pyx_v_bitCount == 32) != 0); if (__pyx_t_6) { @@ -5654,7 +5641,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ * cdef char temp3[3] * if bitCount == 32: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) + * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) * buf[i] = temp4byte */ __pyx_t_7 = __pyx_v_numberOfRecords; @@ -5665,15 +5652,15 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ /* "dataRead.pyx":310 * if bitCount == 32: * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) # <<<<<<<<<<<<<< + * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) # <<<<<<<<<<<<<< * buf[i] = temp4byte * if swap == 0: */ - (void)(memcpy((&__pyx_v_temp4byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), 2)); + (void)(memcpy((&__pyx_v_temp4byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), 4)); /* "dataRead.pyx":311 * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) + * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) * buf[i] = temp4byte # <<<<<<<<<<<<<< * if swap == 0: * return buf @@ -5689,7 +5676,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ } /* "dataRead.pyx":312 - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) + * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) * buf[i] = temp4byte * if swap == 0: # <<<<<<<<<<<<<< * return buf @@ -5711,7 +5698,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ goto __pyx_L0; /* "dataRead.pyx":312 - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) + * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) * buf[i] = temp4byte * if swap == 0: # <<<<<<<<<<<<<< * return buf @@ -5758,7 +5745,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ * cdef char temp3[3] * if bitCount == 32: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) + * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) */ } @@ -6413,7 +6400,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v * cdef char temp3[3] * if bitCount == 32: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) + * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) */ __pyx_t_6 = ((__pyx_v_bitCount == 32) != 0); if (__pyx_t_6) { @@ -6422,7 +6409,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v * cdef char temp3[3] * if bitCount == 32: * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) + * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) * buf[i] = temp4byte */ __pyx_t_7 = __pyx_v_numberOfRecords; @@ -6433,15 +6420,15 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v /* "dataRead.pyx":378 * if bitCount == 32: * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) # <<<<<<<<<<<<<< + * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) # <<<<<<<<<<<<<< * buf[i] = temp4byte * if swap == 0: */ - (void)(memcpy((&__pyx_v_temp4byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), 2)); + (void)(memcpy((&__pyx_v_temp4byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), 4)); /* "dataRead.pyx":379 * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) + * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) * buf[i] = temp4byte # <<<<<<<<<<<<<< * if swap == 0: * return buf @@ -6457,7 +6444,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v } /* "dataRead.pyx":380 - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) + * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) * buf[i] = temp4byte * if swap == 0: # <<<<<<<<<<<<<< * return buf @@ -6479,7 +6466,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v goto __pyx_L0; /* "dataRead.pyx":380 - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) + * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) * buf[i] = temp4byte * if swap == 0: # <<<<<<<<<<<<<< * return buf @@ -6526,7 +6513,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v * cdef char temp3[3] * if bitCount == 32: # <<<<<<<<<<<<<< * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) + * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) */ } From 83f97e25f47e448c6f1b42920b33f158a363c28f Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Tue, 16 Oct 2018 22:11:04 +0200 Subject: [PATCH 26/61] bug for full int32, nBytes was not correct --- dataRead.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dataRead.pyx b/dataRead.pyx index 121b2a3..80fe39b 100644 --- a/dataRead.pyx +++ b/dataRead.pyx @@ -307,7 +307,7 @@ cdef inline dataReadUInt(const char* bita, str RecordFormat, unsigned long long cdef char temp3[3] if bitCount == 32: for i in range(numberOfRecords): - memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) + memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) buf[i] = temp4byte if swap == 0: return buf @@ -375,7 +375,7 @@ cdef inline dataReadInt(const char* bita, str RecordFormat, unsigned long long n cdef char temp3[3] if bitCount == 32: for i in range(numberOfRecords): - memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 2) + memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) buf[i] = temp4byte if swap == 0: return buf From e9458e1d528a240ea052e00cde5af44edc7ab65a Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Tue, 16 Oct 2018 22:11:24 +0200 Subject: [PATCH 27/61] typo correction --- mdfreader/mdf.py | 2 +- mdfreader/mdfreader.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mdfreader/mdf.py b/mdfreader/mdf.py index 81a8fea..c16e332 100644 --- a/mdfreader/mdf.py +++ b/mdfreader/mdf.py @@ -588,7 +588,7 @@ def add_metadata(self, author='', organisation='', project='', self.file_metadata['time'] = time def __str__(self): - """representation a mdf_skeleton class data strucutre + """representation a mdf_skeleton class data structure Returns: ------------ diff --git a/mdfreader/mdfreader.py b/mdfreader/mdfreader.py index 4d1ecd7..366a8a9 100644 --- a/mdfreader/mdfreader.py +++ b/mdfreader/mdfreader.py @@ -519,7 +519,7 @@ def plot(self, channel_name_list_of_list): masterName = list(self.masterChannelList)[0] if not masterName: # resampled channels, only one time channel probably called 'master' masterName = 'master' - master_data = self.getChannelData(master_name) + master_data = self.getChannelData(masterName) if master_data is None: # no master channel master_data = arange(0, len(data), 1) if masterName in self.masterChannelList: # time channel properly defined From 72a373a52ac7547d93dfbbda4bb8480ed596c001 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Mon, 22 Oct 2018 22:54:51 +0200 Subject: [PATCH 28/61] output tuple in getChannelName4 --- mdfreader/mdf4reader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index 81e7de8..3208af7 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -1802,7 +1802,7 @@ def getChannelName4(self, name, path): try: (ndg, ncg, ncn), (cn, cs, cp), (gn, gs, gp) = self[channel_name]['id'] if name == cn and path in (cs, cp) or path in (gn, gs, gp): - output.append(channel_name, (ndg, ncg, ncn)) + output.append((channel_name, (ndg, ncg, ncn))) except KeyError: # most probably a invalid bit channel pass return output From 111ec825f225cc89d5b1c0936c824514a667096f Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Tue, 23 Oct 2018 22:06:44 +0200 Subject: [PATCH 29/61] Added fallback when no unit in master channel to add it based on spec --- mdfreader/mdfinfo4.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mdfreader/mdfinfo4.py b/mdfreader/mdfinfo4.py index d848977..0a4d6d8 100644 --- a/mdfreader/mdfinfo4.py +++ b/mdfreader/mdfinfo4.py @@ -757,6 +757,14 @@ def readCN(self, **kargs): if self['cn_md_unit']: # comments exist self['unit'] = CommentBlock() self['unit'].readCM(fid=kargs['fid'], pointer=self['cn_md_unit'], MDType=1) + if self['cn_sync_type'] and (self['unit'] is None or not self['unit']): + # no units but already known by spec + if self['cn_sync_type'] == 1: + self['unit'] = 's' + elif self['cn_sync_type'] == 2: + self['unit'] = 'rad' + elif self['cn_sync_type'] == 3: + self['unit'] = 'm' if self['cn_tx_name']: # comments exist comment = CommentBlock() comment.readCM(fid=kargs['fid'], pointer=self['cn_tx_name'], MDType=0) From 4199e1602dadc1b77909166fdce420af6590b2ad Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Wed, 24 Oct 2018 01:01:46 +0200 Subject: [PATCH 30/61] Some pep8 refactoring --- mdfreader/channel.py | 16 +- mdfreader/mdf.py | 282 ++++++++++---------- mdfreader/mdf3reader.py | 29 +-- mdfreader/mdf4reader.py | 554 ++++++++++++++++++++-------------------- mdfreader/mdfinfo4.py | 459 ++++++++++++++++----------------- mdfreader/mdfreader.py | 143 +++++------ 6 files changed, 734 insertions(+), 749 deletions(-) diff --git a/mdfreader/channel.py b/mdfreader/channel.py index d7f0778..a95e2b3 100644 --- a/mdfreader/channel.py +++ b/mdfreader/channel.py @@ -19,12 +19,12 @@ from struct import Struct from warnings import warn from .mdfinfo4 import ATBlock -from .mdf import _bits_to_bytes, _convertName +from .mdf import _bits_to_bytes, _convert_name CAN_open_offset = {'ms': 0, 'days': 4, 'minute': 2, 'hour': 3, 'day': 4, 'month': 5, 'year': 6} -class channel4(object): +class Channel4(object): __slots__ = ['channelNumber', 'channelGroup', 'dataGroup', 'type', 'name', 'VLSD_CG_Flag', 'nBytes', 'byteOffset'] """ channel class gathers all about channel structure in a record @@ -447,20 +447,14 @@ def little_endian(self, info): else: return True - def recAttributeName(self, info): + def recAttributeName(self): """ clean up channel name from unauthorised characters - Parameters - ---------------- - - info : mdfinfo4.info4 class - info4 class containing all MDF Blocks - Returns ----------- channel name compliant to python attributes names (for recarray) """ - return _convertName(self.name) + return _convert_name(self.name) def numpy_format(self, info): """ channel numpy.core.records data format @@ -1254,7 +1248,7 @@ def changeChannelName(self, channelGroup): channelGroup bumber """ self.name = '{0}_{1}'.format(self.name, channelGroup) - self.recAttributeName = _convertName(self.name) + self.recAttributeName = _convert_name(self.name) self.RecordFormat = (('{}_title'.format(self.recAttributeName), self.recAttributeName), self.dataFormat) diff --git a/mdfreader/mdf.py b/mdfreader/mdf.py index c16e332..46101df 100644 --- a/mdfreader/mdf.py +++ b/mdfreader/mdf.py @@ -53,12 +53,12 @@ invalidChannel = 'invalid_channel' -class mdf_skeleton(dict): +class MdfSkeleton(dict): __slots__ = ['masterChannelList', 'fileName', 'MDFVersionNumber', 'multiProc', 'convertAfterRead', 'filterChannelNames', 'file_metadata', 'convert_tables', '_pandasframe', 'info', '_compression_level', '_noDataLoading', 'fid', 'zipfile'] - """ mdf_skeleton class + """ MdfSkeleton class Attributes -------------- @@ -130,7 +130,7 @@ def __init__(self, fileName=None, channelList=None, convertAfterRead=True, # flag to control multiprocessing, default deactivate, # giving priority to mdfconverter self.multiProc = False - self.file_metadata = {} + self.file_metadata = dict() self.file_metadata['author'] = '' self.file_metadata['organisation'] = '' self.file_metadata['project'] = '' @@ -157,16 +157,12 @@ def __init__(self, fileName=None, channelList=None, convertAfterRead=True, compression=compression, metadata=metadata) - def add_channel(self, dataGroup, channel_name, data, master_channel, - master_type=1, unit='', description='', conversion=None, - info=None, compression=False, id=None): + def add_channel(self, channel_name, data, master_channel, master_type=1, unit='', description='', conversion=None, + info=None, compression=False, identifier=None): """ adds channel to mdf dict. Parameters ---------------- - dataGroup : int - dataGroup number. Is appended to master name for non unique - channel names channel_name : str channel name data : numpy array @@ -185,7 +181,7 @@ def add_channel(self, dataGroup, channel_name, data, master_channel, used for CABlock axis creation and channel conversion compression : bool flag to ask for channel data compression - id : tuple + identifier : tuple tuple of int and str following below structure: (data group number, channel group number, channel number), (channel name, channel source, channel path), @@ -196,14 +192,14 @@ def add_channel(self, dataGroup, channel_name, data, master_channel, if master_channel not in self.masterChannelList: self.masterChannelList[master_channel] = [] self.masterChannelList[master_channel].append(channel_name) - self.setChannelUnit(channel_name, unit) - self.setChannelDesc(channel_name, description) - self.setChannelMaster(channel_name, master_channel) + self.set_channel_unit(channel_name, unit) + self.set_channel_desc(channel_name, description) + self.set_channel_master(channel_name, master_channel) if self.MDFVersionNumber < 400: # mdf3 - self.setChannelMasterType(channel_name, 1) + self.set_channel_master_type(channel_name, 1) else: # mdf4 - self.setChannelMasterType(channel_name, master_type) - self.setChannelData(channel_name, data, compression) + self.set_channel_master_type(channel_name, master_type) + self.set_channel_data(channel_name, data, compression) if conversion is not None: self[channel_name]['conversion'] = {} self[channel_name]['conversion']['type'] = conversion['cc_type'] @@ -238,8 +234,8 @@ def add_channel(self, dataGroup, channel_name, data, master_channel, else: axis = CABlock['ca_axis_value'] self[channel_name]['axis'] = axis - if id is not None: - self[channel_name]['id'] = id + if identifier is not None: + self[channel_name]['id'] = identifier def remove_channel(self, channel_name): """ removes channel from mdf dict. @@ -253,53 +249,53 @@ def remove_channel(self, channel_name): ------- value of mdf dict key=channel_name """ - self.masterChannelList[self.getChannelMaster(channel_name)].remove(channel_name) + self.masterChannelList[self.get_channel_master(channel_name)].remove(channel_name) return self.pop(channel_name) - def rename_channel(self, channelName, newname): + def rename_channel(self, channel_name, new_name): """Modifies name of channel Parameters ---------------- - channelName : str + channel_name : str channel name - newname : str + new_name : str new channel name """ - if channelName in self and newname not in self: + if channel_name in self and new_name not in self: # add the new name to the same master - self.masterChannelList[self.getChannelMaster(channelName)].append(newname) + self.masterChannelList[self.get_channel_master(channel_name)].append(new_name) # remove the old name - self.masterChannelList[self.getChannelMaster(channelName)].remove(channelName) - self[newname] = self.pop(channelName) # copy the data - if channelName in self.masterChannelList: # it is a master channel - self.masterChannelList[newname] = self.pop(channelName) - for channel in self.masterChannelList[newname]: - self.setChannelMaster(channel, newname) - return self[newname] + self.masterChannelList[self.get_channel_master(channel_name)].remove(channel_name) + self[new_name] = self.pop(channel_name) # copy the data + if channel_name in self.masterChannelList: # it is a master channel + self.masterChannelList[new_name] = self.pop(channel_name) + for channel in self.masterChannelList[new_name]: + self.set_channel_master(channel, new_name) + return self[new_name] else: return None - def remove_channel_conversion(self, channelName): + def remove_channel_conversion(self, channel_name): """ removes conversion key from mdf channel dict. Parameters ---------------- - channelName : str + channel_name : str channel name Returns ------- removed value from dict """ - return self._remove_channel_field(channelName, conversionField) + return self._remove_channel_field(channel_name, conversionField) - def _remove_channel_field(self, channelName, field): + def _remove_channel_field(self, channel_name, field): """general purpose function to remove key from channel dict in mdf Parameters ---------------- - channelName : str + channel_name : str channel name field : str channel dict key @@ -307,16 +303,16 @@ def _remove_channel_field(self, channelName, field): ------- removed value from dict """ - if field in self.getChannel(channelName): - return self[channelName].pop(field) + if field in self.get_channel(channel_name): + return self[channel_name].pop(field) - def getChannelUnit(self, channelName): + def get_channel_unit(self, channel_name): """Returns channel unit string Implemented for a future integration of pint Parameters ---------------- - channelName : str + channel_name : str channel name Returns @@ -324,79 +320,79 @@ def getChannelUnit(self, channelName): str unit string description """ - temp = self._getChannelField(channelName, field=unitField) + temp = self._get_channel_field(channel_name, field=unitField) if isinstance(temp, (dict, defaultdict)): temp = temp['Comment'] return temp - def getChannelDesc(self, channelName): + def get_channel_desc(self, channel_name): """Extract channel description information from mdf structure Parameters ---------------- - channelName : str + channel_name : str channel name Returns ------- channel description string """ - return self._getChannelField(channelName, field=descriptionField) + return self._get_channel_field(channel_name, field=descriptionField) - def getChannelMaster(self, channelName): + def get_channel_master(self, channel_name): """Extract channel master name from mdf structure Parameters ---------------- - channelName : str + channel_name : str channel name Returns ------- channel master name string """ - return self._getChannelField(channelName, field=masterField) + return self._get_channel_field(channel_name, field=masterField) - def getChannelMasterType(self, channelName): + def get_channel_master_type(self, channel_name): """Extract channel master type information from mdf structure Parameters ---------------- - channelName : str + channel_name : str channel name Returns ------- channel mater type integer : 0=None, 1=Time, 2=Angle, 3=Distance, 4=index """ - return self._getChannelField(channelName, field=masterTypeField) + return self._get_channel_field(channel_name, field=masterTypeField) - def getChannelConversion(self, channelName): + def get_channel_conversion(self, channel_name): """Extract channel conversion dict from mdf structure Parameters ---------------- - channelName : str + channel_name : str channel name Returns ------- channel conversion dict """ - return self._getChannelField(channelName, field=conversionField) + return self._get_channel_field(channel_name, field=conversionField) - def getInvalidBit(self, channelName): - return self._getChannelField(channelName, field=invalidPosField) + def get_invalid_bit(self, channel_name): + return self._get_channel_field(channel_name, field=invalidPosField) - def getInvalidChannel(self, channelName): - return self._getChannelField(channelName, field=invalidChannel) + def get_invalid_channel(self, channel_name): + return self._get_channel_field(channel_name, field=invalidChannel) - def getChannel(self, channelName): + def get_channel(self, channel_name): """Extract channel dict from mdf structure Parameters ---------------- - channelName : str + channel_name : str channel name Returns @@ -404,16 +400,16 @@ def getChannel(self, channelName): channel dictionnary containing data, description, unit, etc. """ try: - return self[channelName] + return self[channel_name] except KeyError: return None - def _getChannelField(self, channelName, field=None): + def _get_channel_field(self, channel_name, field=None): """General purpose function to extract channel dict key value from mdf class Parameters ---------------- - channelName : str + channel_name : str channel name field : str channel dict key @@ -421,7 +417,7 @@ def _getChannelField(self, channelName, field=None): ------- channel description string """ - channel = self.getChannel(channelName) + channel = self.get_channel(channel_name) if channel is not None: try: return channel[field] @@ -430,24 +426,24 @@ def _getChannelField(self, channelName, field=None): else: return None - def setChannelUnit(self, channelName, unit): + def set_channel_unit(self, channel_name, unit): """Modifies unit of channel Parameters ---------------- - channelName : str + channel_name : str channel name unit : str channel unit """ - self._setChannel(channelName, unit, field=unitField) + self._set_channel(channel_name, unit, field=unitField) - def setChannelData(self, channelName, data, compression=False): + def set_channel_data(self, channel_name, data, compression=False): """Modifies data of channel Parameters ---------------- - channelName : str + channel_name : str channel name data : numpy array channel data @@ -455,84 +451,84 @@ def setChannelData(self, channelName, data, compression=False): trigger for data compression """ if compression and CompressionPossible: - temp = compressed_data() + temp = CompressedData() temp.compression(data) - self._setChannel(channelName, temp, field=dataField) + self._set_channel(channel_name, temp, field=dataField) else: - self._setChannel(channelName, data, field=dataField) + self._set_channel(channel_name, data, field=dataField) - def setChannelDesc(self, channelName, desc): + def set_channel_desc(self, channel_name, desc): """Modifies description of channel Parameters ---------------- - channelName : str + channel_name : str channel name desc : str channel description """ - self._setChannel(channelName, desc, field=descriptionField) + self._set_channel(channel_name, desc, field=descriptionField) - def setChannelMaster(self, channelName, master): + def set_channel_master(self, channel_name, master): """Modifies channel master name Parameters ---------------- - channelName : str + channel_name : str channel name master : str master channel name """ - self._setChannel(channelName, master, field=masterField) + self._set_channel(channel_name, master, field=masterField) - def setChannelMasterType(self, channelName, masterType): + def set_channel_master_type(self, channel_name, master_type): """Modifies master channel type Parameters ---------------- - channelName : str + channel_name : str channel name - masterType : int + master_type : int master channel type """ - self._setChannel(channelName, masterType, field=masterTypeField) + self._set_channel(channel_name, master_type, field=masterTypeField) - def setChannelConversion(self, channelName, conversion): + def set_channel_conversion(self, channel_name, conversion): """Modifies conversion dict of channel Parameters ---------------- - channelName : str + channel_name : str channel name conversion : dict conversion dictionnary """ - self._setChannel(channelName, conversion, field=conversionField) + self._set_channel(channel_name, conversion, field=conversionField) - def setChannelAttachment(self, channelName, attachment): + def set_channel_attachment(self, channel_name, attachment): """Modifies channel attachment Parameters ---------------- - channelName : str + channel_name : str channel name attachment channel attachment """ - self._setChannel(channelName, attachment, field=attachmentField) + self._set_channel(channel_name, attachment, field=attachmentField) - def setInvalidBit(self, channelName, bit_position): - self[channelName][invalidPosField] = bit_position + def set_invalid_bit(self, channel_name, bit_position): + self[channel_name][invalidPosField] = bit_position - def setInvalidChannel(self, channelName, invalid_channel): - self[channelName][invalidChannel] = invalid_channel + def set_invalid_channel(self, channel_name, invalid_channel): + self[channel_name][invalidChannel] = invalid_channel - def _setChannel(self, channelName, item, field=None): + def _set_channel(self, channel_name, item, field=None): """General purpose method to modify channel values Parameters ---------------- - channelName : str + channel_name : str channel name item new replacing item @@ -540,24 +536,24 @@ def _setChannel(self, channelName, item, field=None): channel dict key of item """ try: - self[channelName][field] = item + self[channel_name][field] = item except KeyError: - warn('Channel {} not in dictionary'.format(channelName)) + warn('Channel {} not in dictionary'.format(channel_name)) - def _channelInMDF(self, channelName): + def _channel_in_mdf(self, channel_name): """Efficiently assess if channel is already in mdf Parameters ---------------- - channelName : str + channel_name : str channel name Return ------- bool """ - return channelName in self.masterChannelList[masterField] \ - or channelName in self.masterChannelList + return channel_name in self.masterChannelList[masterField] \ + or channel_name in self.masterChannelList def add_metadata(self, author='', organisation='', project='', subject='', comment='', date='', time=''): @@ -612,7 +608,7 @@ def __str__(self): output.append('{}\n'.format(d)) for c in self.masterChannelList[d]: output.append(' {} : '.format(c)) - desc = self.getChannelDesc(c) + desc = self.get_channel_desc(c) if desc is not None: try: output.append(str(desc)) @@ -624,7 +620,7 @@ def __str__(self): if data.dtype.kind != 'V': output.append(array_repr(data[:], precision=3, suppress_small=True)) - unit = self.getChannelUnit(c) + unit = self.get_channel_unit(c) if unit is not None: output.append(' {}\n'.format(unit)) return ''.join(output) @@ -645,7 +641,7 @@ def copy(self): mdf_skeleton: class instance copy of a mdf_skeleton class """ - yop = mdf_skeleton() + yop = MdfSkeleton() yop.multiProc = self.multiProc yop.fileName = self.fileName yop.masterChannelList = self.masterChannelList @@ -658,48 +654,48 @@ def copy(self): return yop -def _open_MDF(fileName): +def _open_mdf(file_name): """ Opens mdf, make a few checks and returns fid Parameters ----------- - filename : str + file_name : str filename string - Returns: + Returns -------- fid file identifier """ try: - fid = open(fileName, 'rb') + fid = open(file_name, 'rb') except IOError: - raise Exception('Can not find file {}'.format(fileName)) + raise Exception('Can not find file {}'.format(file_name)) zipfile = False # Check whether file is MDF file -- assumes that every MDF file starts # with the letters MDF if fid.read(3) not in ('MDF', b'MDF'): - if is_zipfile(fileName): + if is_zipfile(file_name): # this is .mfxz file, compressed zip file zipfile = True fid.close() - zip_class = ZipFile(fileName, 'r') + zip_class = ZipFile(file_name, 'r') zip_name = zip_class.namelist()[0] # there should be only one file zip_name = zip_class.extract(zip_name) # locally extracts file fid = open(zip_name, 'rb') - fileName = zip_name + file_name = zip_name else: - raise Exception('file {} is not an MDF file!'.format(fileName)) - return (fid, fileName, zipfile) + raise Exception('file {} is not an MDF file!'.format(file_name)) + return (fid, file_name, zipfile) -def _bits_to_bytes(nBits, numeric=True): +def _bits_to_bytes(n_bits, numeric=True): """ Converts number of bits into number of aligned bytes Parameters ------------- - nBits : int + n_bits : int number of bits numeric: bool flag to indicate channel is numeric @@ -709,54 +705,54 @@ def _bits_to_bytes(nBits, numeric=True): number of equivalent bytes """ if numeric: - if nBits == 0: - nBytes = 0 - elif nBits <= 8: - nBytes = 1 - elif nBits <= 16: - nBytes = 2 - elif nBits <= 32: - nBytes = 4 - elif nBits <= 64: - nBytes = 8 + if n_bits == 0: + n_bytes = 0 + elif n_bits <= 8: + n_bytes = 1 + elif n_bits <= 16: + n_bytes = 2 + elif n_bits <= 32: + n_bytes = 4 + elif n_bits <= 64: + n_bytes = 8 else: warn('error converting bits into bytes for a numeric channel, too many bits') - nBytes = nBits // 8 - if not nBits % 8 == 0: - nBytes += 1 + n_bytes = n_bits // 8 + if not n_bits % 8 == 0: + n_bytes += 1 else: - nBytes = nBits // 8 - if not nBits % 8 == 0: - nBytes += 1 - return nBytes + n_bytes = n_bits // 8 + if not n_bits % 8 == 0: + n_bytes += 1 + return n_bytes -def _convertName(channelName): +def _convert_name(channel_name): """ Check if channelName is valid python identifier to be removed with next function if no more need """ if PythonVersion < 3: # python 2 - channelIdentifier = _sanitize_identifier(channelName).encode('utf-8') + channel_identifier = _sanitize_identifier(channel_name).encode('utf-8') else: # python 3 - if channelName.isidentifier(): - return channelName + if channel_name.isidentifier(): + return channel_name else: - channelIdentifier = str(_sanitize_identifier(channelName)) + channel_identifier = str(_sanitize_identifier(channel_name)) # all characters of channel are not compliant to python - if not channelIdentifier: + if not channel_identifier: # generate random name for recarray - channelIdentifier = ''.join([choice(ascii_letters) for n in range(32)]) - if channelIdentifier in _notAllowedChannelNames: + channel_identifier = ''.join([choice(ascii_letters) for n in range(32)]) + if channel_identifier in _notAllowedChannelNames: # limitation from recarray object attribute - channelIdentifier = ''.join([channelIdentifier, '_']) - return channelIdentifier + channel_identifier = ''.join([channel_identifier, '_']) + return channel_identifier def _gen_valid_identifier(seq): # get an iterator itr = iter(seq) - # pull characters until we get a legal one for first in identifer + # pull characters until we get a legal one for first in identifier for ch in itr: if ch == '_' or ch.isalpha(): yield ch @@ -776,7 +772,7 @@ def _sanitize_identifier(name): return ''.join(_gen_valid_identifier(name)) -class compressed_data(): +class CompressedData: __slots__ = ['data', 'dtype'] """ class to represent compressed data by blosc """ diff --git a/mdfreader/mdf3reader.py b/mdfreader/mdf3reader.py index 5906b0e..e005829 100644 --- a/mdfreader/mdf3reader.py +++ b/mdfreader/mdf3reader.py @@ -32,8 +32,8 @@ from warnings import warn import os from warnings import simplefilter -from .mdf import mdf_skeleton, _open_MDF, \ - dataField, conversionField, idField, compressed_data +from .mdf import MdfSkeleton, _open_mdf, \ + dataField, conversionField, idField, CompressedData from .mdfinfo3 import info3 from .channel import Channel3 if os.name == 'posix': @@ -777,7 +777,7 @@ def loadUnSorted(self, nameList=None): return buf -class mdf3(mdf_skeleton): +class mdf3(MdfSkeleton): """ mdf file version 3.0 to 3.3 class @@ -967,13 +967,8 @@ def read3(self, fileName=None, info=None, multiProc=False, channelList=None, temp = bitwise_and(temp, mask) else: # should not happen warn('bit count and offset not applied to correct data type') - self.add_channel(dataGroup, chan.name, temp, - master_channel, - master_type=1, - unit=chan.unit, - description=chan.desc, - conversion=chan.conversion, - info=None, + self.add_channel(chan.name, temp, master_channel, master_type=1, unit=chan.unit, + description=chan.desc, conversion=chan.conversion, info=None, compression=compression) buf[recordID].pop('data', None) del buf @@ -1005,15 +1000,15 @@ def _getChannelData3(self, channelName, raw_data=False): This method is the safest to get channel data as numpy array from 'data' dict key might contain raw data """ if channelName in self: - vect = self.getChannel(channelName)[dataField] + vect = self.get_channel(channelName)[dataField] if vect is None: # noDataLoading reading argument flag activated if self.info.fid is None or (self.info.fid is not None and self.info.fid.closed): - (self.info.fid, self.info.fileName, zipfile) = _open_MDF(self.fileName) + (self.info.fid, self.info.fileName, zipfile) = _open_mdf(self.fileName) self.read3(fileName=None, info=self.info, channelList=[channelName], convertAfterRead=False) if not raw_data: return self._convert3(channelName, self.convert_tables) else: - return self.getChannel(channelName)[dataField] + return self.get_channel(channelName)[dataField] else: return None @@ -1036,7 +1031,7 @@ def _convert3(self, channelName, convert_tables=False): if self[channelName][dataField] is None: vect = self[channelName][dataField] else: - if isinstance(self[channelName][dataField], compressed_data): + if isinstance(self[channelName][dataField], CompressedData): vect = self[channelName][dataField].decompression() # uncompress blosc else: vect = self[channelName][dataField][:] # to have bcolz uncompressed data @@ -1075,7 +1070,7 @@ def _convertChannel3(self, channelName): channelName : str Name of channel """ - self.setChannelData(channelName, self._convert3(channelName, self.convert_tables)) + self.set_channel_data(channelName, self._convert3(channelName, self.convert_tables)) self.remove_channel_conversion(channelName) def _convertAllChannel3(self): @@ -1246,7 +1241,7 @@ def writePointer(f, pointer, value): masterFlag = 0 # data channel else: masterFlag = 1 # master channel - desc = self.getChannelDesc(channel) + desc = self.get_channel_desc(channel) #if bitOffset exceeds two byte limit, we start using the byte offset field if bitOffset > 0xFFFF: bitOffset -= 0x10000 @@ -1325,7 +1320,7 @@ def writePointer(f, pointer, value): # conversion already done during reading # additional size information, not necessary for 65535 conversion type ? try: - unit = '{:\x00<20.19}'.format(self.getChannelUnit(channel) + unit = '{:\x00<20.19}'.format(self.get_channel_unit(channel) .encode('latin-1', 'replace')) except: unit = b'\x00' * 20 diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index 3208af7..3ce5a92 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -39,23 +39,23 @@ from collections import defaultdict, OrderedDict from numpy.core.records import fromstring, fromarrays from numpy import array, recarray, asarray, empty, where, frombuffer, reshape -from numpy import arange, right_shift, bitwise_and, bitwise_or, all, diff, interp +from numpy import arange, right_shift, bitwise_and, all, diff, interp from numpy import issubdtype, number as numpy_number from numpy import max as npmax, min as npmin from numpy.lib.recfunctions import rec_append_fields, rename_fields from numpy.ma import MaskedArray from warnings import simplefilter, warn -from .mdfinfo4 import info4, IDBlock, HDBlock, DGBlock, \ - CGBlock, CNBlock, FHBlock, CommentBlock, _loadHeader, DLBlock, \ +from .mdfinfo4 import Info4, IDBlock, HDBlock, DGBlock, \ + CGBlock, CNBlock, FHBlock, CommentBlock, _load_header, DLBlock, \ DZBlock, HLBlock, CCBlock, DTBlock, CABlock -from .mdf import mdf_skeleton, _open_MDF, invalidChannel, dataField, \ - conversionField, idField, invalidPosField, compressed_data -from .channel import channel4 +from .mdf import MdfSkeleton, _open_mdf, invalidChannel, dataField, \ + conversionField, idField, invalidPosField, CompressedData +from .channel import Channel4 try: from dataRead import dataRead dataRead_available = True except ImportError: - warn('dataRead cannot be imported, compile it with cython', ImportWarning) + warn('dataRead cannot be imported, compile it with Cython', ImportWarning) dataRead_available = False PythonVersion = version_info @@ -64,8 +64,8 @@ chunk_size_reading = 100000000 # reads by chunk of 100Mb, can be tuned for best performance -def DATABlock(record, info, parent_block, channelSet=None, nrecords=None, sortedFlag=True, vlsd=False): - """ DATABlock converts raw data into arrays +def _data_block(record, info, parent_block, channel_set=None, nrecords=None, sorted_flag=True, vlsd=False): + """ converts raw data into arrays Parameters ---------------- @@ -73,12 +73,12 @@ def DATABlock(record, info, parent_block, channelSet=None, nrecords=None, sorted record class instance describing a channel group record parent_block : class MDFBlock class containing at least parent block header - channelSet : set of str, optional + channel_set : set of str, optional defines set of channels to only read, can be slow but saves memory, for big files nrecords: int, optional number of records to read - sortedFlag : bool, optional + sorted_flag : bool, optional flag to know if data block is sorted (only one Channel Group in block) or unsorted (several Channel Groups identified by a recordID). As unsorted block can contain CG records in random order, block @@ -98,8 +98,8 @@ def DATABlock(record, info, parent_block, channelSet=None, nrecords=None, sorted if nrecords is None and hasattr(record, 'numberOfRecords'): nrecords = record.numberOfRecords if parent_block['id'] in ('##DT', '##RD', b'##DT', b'##RD'): # normal data block - if sortedFlag: - if channelSet is None and not record.hiddenBytes and\ + if sorted_flag: + if channel_set is None and not record.hiddenBytes and\ record.byte_aligned: # No channel list and length of records corresponds to C datatypes # for debugging purpose # print(nrecords, record.numpyDataRecordFormat, record.dataRecordName) @@ -107,35 +107,35 @@ def DATABlock(record, info, parent_block, channelSet=None, nrecords=None, sorted 'formats': record.numpyDataRecordFormat}, shape=nrecords) else: # record is not byte aligned or channelSet not None - return record.read_channels_from_bytes(parent_block['data'], info, channelSet, nrecords) + return record.read_channels_from_bytes(parent_block['data'], info, channel_set, nrecords) else: # unsorted reading - return readUnsorted(record, info, parent_block, channelSet) + return _read_unsorted(record, info, parent_block, channel_set) elif parent_block['id'] in ('##SD', b'##SD'): - return read_sdblock(record[record.VLSD[0]].signalDataType(info), - parent_block['data'], parent_block['length'] - 24) + return _read_sdblock(record[record.VLSD[0]].signalDataType(info), parent_block['data'], + parent_block['length'] - 24) elif parent_block['id'] in ('##DZ', b'##DZ'): # zipped data block # uncompress data parent_block['data'] = DZBlock.decompress_datablock(parent_block['data'], parent_block['dz_zip_type'], parent_block['dz_zip_parameter'], parent_block['dz_org_data_length']) if vlsd: # VLSD channel - return read_sdblock(record[record.VLSD[0]].signalDataType(info), - parent_block['data'], parent_block['dz_org_data_length']) - if channelSet is None and sortedFlag: # reads all blocks if sorted block and no channelSet defined + return _read_sdblock(record[record.VLSD[0]].signalDataType(info), parent_block['data'], + parent_block['dz_org_data_length']) + if channel_set is None and sorted_flag: # reads all blocks if sorted block and no channelSet defined if record.byte_aligned and not record.hiddenBytes: return fromstring(parent_block['data'], dtype={'names': record.dataRecordName, 'formats': record.numpyDataRecordFormat}, shape=nrecords) else: - return record.read_channels_from_bytes(parent_block['data'], info, channelSet, nrecords) - elif channelSet is not None and sortedFlag: # sorted data but channel list requested - return record.read_channels_from_bytes(parent_block['data'], info, channelSet, nrecords) + return record.read_channels_from_bytes(parent_block['data'], info, channel_set, nrecords) + elif channel_set is not None and sorted_flag: # sorted data but channel list requested + return record.read_channels_from_bytes(parent_block['data'], info, channel_set, nrecords) else: # unsorted reading - return readUnsorted(record, info, parent_block, channelSet) + return _read_unsorted(record, info, parent_block, channel_set) -def readUnsorted(record, info, parent_block, channelSet=None): +def _read_unsorted(record, info, parent_block, channel_set=None): # reads only the channels using offset functions, channel by channel. buf = defaultdict(list) position = 0 @@ -151,7 +151,8 @@ def readUnsorted(record, info, parent_block, channelSet=None): while position < len(parent_block['data']): recordID = recordIdCFormat.unpack(parent_block['data'][position:position + recordIDsize])[0] if not record[recordID]['record'].Flags & 0b1: # not VLSD CG) - temp = record.readRecord(recordID, info, parent_block['data'][position:position + record[recordID]['record'].CGrecordLength + 1], channelSet) + temp = record.read_record(recordID, info, parent_block['data'][position:position + record[recordID][ + 'record'].CGrecordLength + 1], channel_set) position += record[recordID]['record'].CGrecordLength for channelName in temp: buf[channelName].append(temp[channelName]) @@ -177,7 +178,7 @@ def readUnsorted(record, info, parent_block, channelSet=None): return buf -def read_sdblock(signal_data_type, sdblock, sdblock_length): +def _read_sdblock(signal_data_type, sdblock, sdblock_length): """ Reads vlsd channel from its SD Block bytes Parameters @@ -210,11 +211,11 @@ def read_sdblock(signal_data_type, sdblock, sdblock_length): pointer += 4 buf.append(sdblock[pointer:pointer + VLSDLen].decode(channel_format).rstrip('\x00')) pointer += VLSDLen - buf = equalizeStringLength(buf) + buf = _equalize_string_length(buf) return array(buf) -def equalizeStringLength(buf): +def _equalize_string_length(buf): """ Makes all strings in a list having same length by appending spaces strings. Parameters @@ -231,31 +232,31 @@ def equalizeStringLength(buf): return buf -class DATA(dict): - __slots__ = ['fid', 'pointerTodata', 'type'] - """ DATA class is organizing record classes itself made of channel class. +class Data(dict): + __slots__ = ['fid', 'pointer_to_data', 'type'] + """ Data class is organizing record classes itself made of channel class. This class inherits from dict. Keys are corresponding to channel group recordID - A DATA class corresponds to a data block, a dict of record classes (one per channel group) + A Dataclass corresponds to a data block, a dict of record classes (one per channel group) Each record class contains a list of channel class representing the structure of channel record. Attributes -------------- fid : io.open file identifier - pointerToData : int + pointer_to_data : int position of Data block in mdf file type : str 'sorted' or 'unsorted' data block Methods ------------ - addRecord(record) + add_record(record) Adds a new record in DATA class dict - read(channelSet, zip=None) + read(channel_set, zip=None) Reads data block - load(record, zip=None, nameList=None) + load(record, zip=None, name_list=None) Reads sorted data block from record definition - readRecord(recordID, buf, channelSet=None): + read_record(recordID, buf, channel_set=None): read record from a buffer """ @@ -270,11 +271,11 @@ def __init__(self, fid, pointer): position of data block in file """ self.fid = fid - self.pointerTodata = pointer + self.pointer_to_data = pointer self.type = 'sorted' - def addRecord(self, record): - """Adds a new record in DATA class dict. + def add_record(self, record): + """Adds a new record in Data class dict. Parameters ---------------- @@ -287,12 +288,12 @@ def addRecord(self, record): for recordID in self[record.recordID]['record'].VLSD_CG: self[recordID]['record'].VLSD_CG = self[record.recordID]['record'].VLSD_CG - def read(self, channelSet, info, filename): + def read(self, channel_set, info, filename): """Reads data block Parameters ---------------- - channelSet : set of str + channel_set : set of str set of channel names info : info object contains blocks structures @@ -305,35 +306,35 @@ def read(self, channelSet, info, filename): if len(self) == 1: # sorted dataGroup recordID = list(self.keys())[0] record = self[recordID]['record'] - self[recordID]['data'] = self.load(record, info, nameList=channelSet, sortedFlag=True) + self[recordID]['data'] = self.load(record, info, name_list=channel_set, sorted_flag=True) for cn in record.VLSD: # VLSD channels - if channelSet is None or record[cn].name in channelSet: - temp = DATA(self.fid, record[cn].data(info)) # all channels - temp = temp.load(record, info, nameList=channelSet, sortedFlag=True, vlsd=True) + if channel_set is None or record[cn].name in channel_set: + temp = Data(self.fid, record[cn].data(info)) # all channels + temp = temp.load(record, info, name_list=channel_set, sorted_flag=True, vlsd=True) self[recordID]['data'] = rename_fields(self[recordID]['data'], {record[cn].name: '{}_offset'.format(record[cn].name)}) self[recordID]['data'] = rec_append_fields(self[recordID]['data'], record[cn].name, temp) else: # unsorted DataGroup self.type = 'unsorted' - data = self.load(self, info, nameList=channelSet, sortedFlag=False) + data = self.load(self, info, name_list=channel_set, sorted_flag=False) for recordID in self: self[recordID]['data'] = {} for channel in self[recordID]['record']: self[recordID]['data'][channel.name] = data[channel.name] - def load(self, record, info, nameList=None, sortedFlag=True, vlsd=False): + def load(self, record, info, name_list=None, sorted_flag=True, vlsd=False): """Reads data block from record definition Parameters ---------------- - record class + record : class channel group definition listing record channel classes - info class + info : class contains blocks - nameList : list of str, optional + name_list : list of str, optional list of channel names - sortedFlag : bool, optional + sorted_flag : bool, optional flag to know if data block is sorted (only one Channel Group in block) or unsorted (several Channel Groups identified by a recordID). As unsorted block can contain CG records in random order, block @@ -347,7 +348,7 @@ def load(self, record, info, nameList=None, sortedFlag=True, vlsd=False): """ temps = defaultdict() # block header - temps.update(_loadHeader(self.fid, self.pointerTodata)) + temps.update(_load_header(self.fid, self.pointer_to_data)) if temps['id'] in ('##DL', b'##DL'): # data list block temp = DLBlock() temp.read(self.fid, temps['link_count']) @@ -356,7 +357,7 @@ def load(self, record, info, nameList=None, sortedFlag=True, vlsd=False): index = 1 while temps['dl_dl_next']: # reads pointers to all data blocks (DT, RD, SD, DZ) temp = defaultdict() - temp.update(_loadHeader(self.fid, temps['dl_dl_next'])) + temp.update(_load_header(self.fid, temps['dl_dl_next'])) temps['dl_dl_next'] = structunpack(' record.numberOfRecords: # there could be more data than needed for the expected number of records nrecord_chunk = record.numberOfRecords - previous_index - tmp = DATABlock(record, info, parent_block=data_block, - channelSet=nameList, nrecords=nrecord_chunk, - sortedFlag=sortedFlag, vlsd=vlsd) + tmp = _data_block(record, info, parent_block=data_block, channel_set=name_list, + nrecords=nrecord_chunk, sorted_flag=sorted_flag, vlsd=vlsd) if 'data' not in temps: # initialise recarray temps['data'] = recarray(record.numberOfRecords, dtype=tmp.dtype) temps['data'][previous_index: previous_index + nrecord_chunk] = tmp @@ -437,51 +436,50 @@ def load(self, record, info, nameList=None, sortedFlag=True, vlsd=False): temp = HLBlock() temp.read(self.fid) temps.update(temp) - self.pointerTodata = temps['hl_dl_first'] - temps['data'] = self.load(record, info, nameList=nameList, sortedFlag=sortedFlag, vlsd=vlsd) + self.pointer_to_data = temps['hl_dl_first'] + temps['data'] = self.load(record, info, name_list=name_list, sorted_flag=sorted_flag, vlsd=vlsd) elif temps['id'] in ('##DT', '##RD', b'##DT', b'##RD'): # normal sorted data block, direct read - temps['data'] = record.readSortedRecord(self.fid, info, channelSet=nameList) + temps['data'] = record.readSortedRecord(self.fid, info, channelSet=name_list) elif temps['id'] in ('##SD', b'##SD'): # VLSD temps['data'] = self.fid.read(temps['length'] - 24) - temps['data'] = DATABlock(record, info, parent_block=temps, channelSet=nameList, - nrecords=None, sortedFlag=sortedFlag) + temps['data'] = _data_block(record, info, parent_block=temps, channel_set=name_list, nrecords=None, + sorted_flag=sorted_flag) elif temps['id'] in ('##DZ', b'##DZ'): # zipped data block temp = DZBlock() temp.read(self.fid) temps.update(temp) temps['data'] = self.fid.read(temps['dz_data_length']) - temps['data'] = DATABlock(record, info, parent_block=temps, - channelSet=nameList, nrecords=None, - sortedFlag=sortedFlag, vlsd=vlsd) + temps['data'] = _data_block(record, info, parent_block=temps, channel_set=name_list, nrecords=None, + sorted_flag=sorted_flag, vlsd=vlsd) else: raise Exception('unknown data block') return temps['data'] - def readRecord(self, recordID, info, buf, channelSet=None): + def read_record(self, recordID, info, buf, channel_set=None): """ read record from a buffer Parameters ---------------- recordID : int record identifier - info class + info : class contains blocks buf : str buffer of data from file to be converted to channel raw data - channelSet : set of str - setof channel names to be read + channel_set : set of str + set of channel names to be read """ - return self[recordID]['record'].readRecordBuf(buf, info, channelSet) + return self[recordID]['record'].readRecordBuf(buf, info, channel_set) -class record(list): +class Record(list): __slots__ = ['CGrecordLength', 'recordLength', 'numberOfRecords', 'recordID', 'recordIDsize', 'recordIDCFormat', 'dataGroup', 'channelGroup', 'numpyDataRecordFormat', 'dataRecordName', 'master', 'recordToChannelMatching', 'channelNames', 'Flags', 'VLSD_CG', 'VLSD', 'MLSD', 'byte_aligned', 'hiddenBytes', 'invalid_channel', 'CANOpen'] - """ record class listing channel classes. It is representing a channel group + """ Record class listing channel classes. It is representing a channel group Attributes -------------- @@ -530,11 +528,16 @@ class record(list): Methods ------------ - addChannel(info, channelNumber) - loadInfo(info) + add_channel(info, channelNumber) + load_info(info) readSortedRecord(fid, pointer, info, channelSet=None) + generate_chunks() + read_all_channels_sorted_record(fid) + read_not_all_channels_sorted_record(fid, info, channelSet) readRecordBuf(buf, info, channelSet=None) - read_channels_from_bytes(bita, info, channelSet=None) + initialise_recarray(info, channel_set, nrecords, dtype=None, channels_indexes=None) + read_channels_from_bytes(bita, info, channelSet=None, nrecords=None, dtype=None, channels_indexes=None) + read_channels_from_bytes_fallback(bita, info, channel_set=None, nrecords=None, dtype=None, channels_indexes=None) """ def __init__(self, dataGroup, channelGroup): @@ -584,20 +587,20 @@ def __str__(self): output.append('\nVLSD_CG {}\n'.format(self.VLSD_CG)) return ''.join(output) - def addChannel(self, info, channelNumber): + def add_channel(self, info, channel_number): """ add a channel in class Parameters ---------------- info : mdfinfo4.info4 class - channelNumber : int + channel_number : int channel number in mdfinfo4.info4 class """ - Channel = channel4() - self.append(Channel.set(info, self.dataGroup, self.channelGroup, channelNumber)) + Channel = Channel4() + self.append(Channel.set(info, self.dataGroup, self.channelGroup, channel_number)) self.channelNames.add(self[-1].name) - def loadInfo(self, info): + def load_info(self, info): """ gathers records related from info class Parameters @@ -635,7 +638,7 @@ def loadInfo(self, info): self.MLSD = info['MLSD'] embedding_channel = None for channelNumber in info['CN'][self.dataGroup][self.channelGroup]: - Channel = channel4() + Channel = Channel4() Channel.set(info, self.dataGroup, self.channelGroup, channelNumber) channelType = Channel.channelType(info) dataFormat = Channel.dataFormat(info) @@ -649,7 +652,7 @@ def loadInfo(self, info): signalDataType = Channel.signalDataType(info) if signalDataType == 13: for name in ('ms', 'minute', 'hour', 'day', 'month', 'year'): - Channel = channel4() # new object otherwise only modified + Channel = Channel4() # new object otherwise only modified Channel.setCANOpen(info, self.dataGroup, self.channelGroup, channelNumber, name) self.append(Channel) self.channelNames.add(name) @@ -661,7 +664,7 @@ def loadInfo(self, info): embedding_channel = None elif signalDataType == 14: for name in ('ms', 'days'): - Channel = channel4() + Channel = Channel4() Channel.setCANOpen(info, self.dataGroup, self.channelGroup, channelNumber, name) self.append(Channel) self.channelNames.add(name) @@ -732,7 +735,7 @@ def loadInfo(self, info): if info['CG'][self.dataGroup][self.channelGroup]['cg_invalid_bytes']: # invalid bytes existing self.CGrecordLength += info['CG'][self.dataGroup][self.channelGroup]['cg_invalid_bytes'] self.recordLength += info['CG'][self.dataGroup][self.channelGroup]['cg_invalid_bytes'] - invalid_bytes = channel4() + invalid_bytes = Channel4() invalid_bytes.setInvalidBytes(info, self.dataGroup, self.channelGroup, channelNumber + 1) self.invalid_channel = invalid_bytes self.append(self.invalid_channel) @@ -855,8 +858,7 @@ def read_not_all_channels_sorted_record(self, fid, info, channelSet): else: for nrecord_chunk, chunk_size in chunks: rec[previous_index: previous_index + nrecord_chunk] = \ - self.read_channels_from_bytes_fallback(fid.read(chunk_size), - info, channelSet, nrecord_chunk, + self.read_channels_from_bytes_fallback(fid.read(chunk_size), info, channelSet, nrecord_chunk, rec.dtype, channels_indexes) previous_index += nrecord_chunk return rec @@ -890,13 +892,13 @@ def readRecordBuf(self, buf, info, channelSet=None): Channel.CFormat(info).unpack(buf[Channel.posByteBeg(info):Channel.posByteEnd(info)])[0] return temp # returns dictionary of channel with its corresponding values - def initialise_recarray(self, info, channelSet, nrecords, dtype=None, channels_indexes=None): + def initialise_recarray(self, info, channel_set, nrecords, dtype=None, channels_indexes=None): """ Initialise recarray Parameters ------------ info: info class - channelSet : set of str, optional + channel_set : set of str, optional set of channel to read nrecords: int number of records @@ -911,13 +913,13 @@ def initialise_recarray(self, info, channelSet, nrecords, dtype=None, channels_i if dtype is not None and channels_indexes is not None: return recarray(nrecords, dtype=dtype), channels_indexes else: - if channelSet is None: - channelSet = self.channelNames + if channel_set is None: + channel_set = self.channelNames formats = [] names = [] channels_indexes = [] for chan in range(len(self)): - if self[chan].name in channelSet and self[chan].channelType(info) not in (3, 6): + if self[chan].name in channel_set and self[chan].channelType(info) not in (3, 6): # not virtual channel and part of channelSet channels_indexes.append(chan) formats.append(self[chan].nativedataFormat(info)) @@ -978,8 +980,8 @@ def read_channels_from_bytes(self, bita, info, channelSet=None, nrecords=None, else: return [] - def read_channels_from_bytes_fallback(self, bita, info, channelSet=None, nrecords=None, - dtype=None, channels_indexes=None): + def read_channels_from_bytes_fallback(self, bita, info, channel_set=None, nrecords=None, dtype=None, + channels_indexes=None): """ reads stream of record bytes using bitarray in case no dataRead available Parameters @@ -987,7 +989,7 @@ def read_channels_from_bytes_fallback(self, bita, info, channelSet=None, nrecord bita : stream stream of bytes info: info class - channelSet : set of str, optional + channel_set : set of str, optional set of channel to read nrecords: int number of records @@ -1018,7 +1020,7 @@ def signedInt(temp, extension): if nrecords is None: nrecords = self.numberOfRecords if dtype is None: - buf, channels_indexes = self.initialise_recarray(info, channelSet, nrecords, dtype, channels_indexes) + buf, channels_indexes = self.initialise_recarray(info, channel_set, nrecords, dtype, channels_indexes) else: buf = recarray(nrecords, dtype=dtype) if buf is not None: @@ -1075,7 +1077,7 @@ def signedInt(temp, extension): return [] -class mdf4(mdf_skeleton): +class Mdf4(MdfSkeleton): """ mdf file reader class from version 4.0 to 4.1.1 @@ -1102,21 +1104,29 @@ class mdf4(mdf_skeleton): ------------ read4( fileName=None, info=None, multiProc=False, channelList=None, convertAfterRead=True) Reads mdf 4.x file data and stores it in dict - _getChannelData4(channelName) + _get_channel_data_4(channelName) Returns channel numpy array - _convertChannel4(channelName) + _convert_channel_data_4(channel, channel_name, convert_tables, multiProc=False, Q=None) + select right conversion and calculates it + _convert_channel_4(channelName) converts specific channel from raw to physical data according to CCBlock information - _convertAllChannel4() + _convert_all_channel_4() Converts all channels from raw data to converted data according to CCBlock information + write4(file_name=None, compression=False) + writes mdf 4.1 file + apply_invalid_bit(channel_name) + mask data from invalid bit channel if existing + get_channel_name_4(name, path) + returns a list of tuples """ - def read4(self, fileName=None, info=None, multiProc=False, channelList=None, - convertAfterRead=True, compression=False, metadata=2): + def read4(self, file_name=None, info=None, multiProc=False, channel_list=None, convert_after_read=True, + compression=False, metadata=2): """ Reads mdf 4.x file data and stores it in dict Parameters ---------------- - fileName : str, optional + file_name : str, optional file name info : mdfinfo4.info4 class @@ -1125,12 +1135,12 @@ def read4(self, fileName=None, info=None, multiProc=False, channelList=None, multiProc : bool flag to activate multiprocessing of channel data conversion - channelList : list of str, optional + channel_list : list of str, optional list of channel names to be read If you use channelList, reading might be much slower but it will save you memory. Can be used to read big files - convertAfterRead : bool, optional + convert_after_read : bool, optional flag to convert channel after read, True by default If you use convertAfterRead by setting it to false, all data from channels will be kept raw, no conversion applied. @@ -1152,22 +1162,22 @@ def read4(self, fileName=None, info=None, multiProc=False, channelList=None, if self.fileName is None and info is not None: self.fileName = info.fileName - elif fileName is not None and self.fileName is None: - self.fileName = fileName + elif file_name is not None and self.fileName is None: + self.fileName = file_name minimal = metadata # always read minimum info (2), full info (0) # set is more efficient for large number of channels (n^2 vs n*log(n)): - if channelList is not None: - channelSetFile = set(channelList) # make sure it is a set + if channel_list is not None: + channel_set_file = set(channel_list) # make sure it is a set minimal = 1 # reads at least CN to populate ChannelNamesByDG else: - channelSetFile = None + channel_set_file = None # Read information block from file if info is None: if self.info is None: - info = info4(self.fileName, None, minimal=minimal) + info = Info4(self.fileName, None, minimal=minimal) else: info = self.info @@ -1193,32 +1203,32 @@ def returnField(obj, field): subject = returnField(Comment, 'subject') comment = returnField(Comment, 'TX') self.add_metadata(author=author, organisation=organisation, - project=project, subject=subject, comment=comment, - date=ddate, time=ttime) + project=project, subject=subject, comment=comment, + date=ddate, time=ttime) else: self.add_metadata(date=ddate, time=ttime) data_groups = info['DG'] # parse all data groups - if self._noDataLoading and channelList is not None: - data_groups = [self[channel][idField][0] for channel in channelList] + if self._noDataLoading and channel_list is not None: + data_groups = [self[channel][idField][0] for channel in channel_list] for dataGroup in data_groups: - channelSet = channelSetFile + channelSet = channel_set_file if not info['DG'][dataGroup]['dg_data'] == 0 and \ (channelSet is None or len(channelSet & info['ChannelNamesByDG'][dataGroup]) > 0): # there is data block and channel in if minimal > 1 and not self._noDataLoading: # load CG, CN and CC block info - info.readCGBlock(info.fid, dataGroup, channelSet, minimal=minimal) + info.read_CGBlock(info.fid, dataGroup, channelSet, minimal=minimal) if info['CG'][dataGroup][0]['cg_cycle_count']: # data exists # Pointer to data block pointerToData = info['DG'][dataGroup]['dg_data'] if 'dataClass' not in info['DG'][dataGroup]: - buf = DATA(info.fid, pointerToData) + buf = Data(info.fid, pointerToData) for channelGroup in info['CG'][dataGroup]: - temp = record(dataGroup, channelGroup) # create record class - temp.loadInfo(info) # load all info related to record - buf.addRecord(temp) # adds record to DATA + temp = Record(dataGroup, channelGroup) # create record class + temp.load_info(info) # load all info related to record + buf.add_record(temp) # adds record to DATA recordID = info['CG'][dataGroup][channelGroup]['cg_record_id'] if temp.master['name'] is not None \ and buf[recordID]['record'].channelNames: @@ -1236,13 +1246,13 @@ def returnField(obj, field): else: buf = self.info['DG'][dataGroup]['dataClass'] - # reads raw data from data block with DATA and DATABlock classes + # reads raw data from data block with DATA and _data_block classes buf.read(channelSet, info, self.fileName) channel_groups = buf - if self._noDataLoading and channelList is not None: + if self._noDataLoading and channel_list is not None: channel_groups = [info['CG'][dataGroup][self[channel][idField][1]]['cg_record_id'] - for channel in channelList] + for channel in channel_list] # processing data from buf then transfer to self for recordID in channel_groups: # for each channel group in data block @@ -1250,8 +1260,8 @@ def returnField(obj, field): master_channel = buf[recordID]['record'].master['name'] channels = buf[recordID]['record'] - if self._noDataLoading and channelList is not None: - channels = [channels[self[channel][idField][2]] for channel in channelList] + if self._noDataLoading and channel_list is not None: + channels = [channels[self[channel][idField][2]] for channel in channel_list] for chan in channels: # for each channel class if channelSet is None or chan.name in channelSet: if not chan.type == 4: # normal channel @@ -1326,37 +1336,28 @@ def returnField(obj, field): temp = temp2 # channel creation - self.add_channel(dataGroup, chan.name, temp, - master_channel, + self.add_channel(chan.name, temp, master_channel, master_type=chan.channelSyncType(info), - unit=chan.unit(info), - description=chan.desc(info), - conversion=chan.conversion(info), - info=chan.CNBlock(info), + unit=chan.unit(info), description=chan.desc(info), + conversion=chan.conversion(info), info=chan.CNBlock(info), compression=compression, - id=info.unique_id(chan.dataGroup, - chan.channelGroup, - chan.channelNumber)) + identifier=info.unique_id(chan.dataGroup, + chan.channelGroup, + chan.channelNumber)) if chan.channelType(info) == 4: # sync channel # attach stream to be synchronised - self.setChannelAttachment(chan.name, chan.attachment(info.fid, info)) + self.set_channel_attachment(chan.name, chan.attachment(info.fid, info)) if chan.has_invalid_bit(info): # has invalid bit - self.setInvalidBit(chan.name, chan.invalid_bit(info)) - self.setInvalidChannel(chan.name, 'invalid_bytes{}'.format(dataGroup)) + self.set_invalid_bit(chan.name, chan.invalid_bit(info)) + self.set_invalid_channel(chan.name, 'invalid_bytes{}'.format(dataGroup)) else: # invalid bytes channel data = buf[recordID]['data'].__getattribute__(chan.name) data = frombuffer(data.tobytes(), dtype='u1').reshape(len(data), data.dtype.itemsize) - self.add_channel(dataGroup, chan.name, - data, - master_channel, - master_type=0, - unit='', - description='', - info=None, - compression=compression, - id=None) + self.add_channel(chan.name, data, master_channel, master_type=0, unit='', + description='', info=None, compression=compression, + identifier=None) buf[recordID].pop('data', None) del buf if minimal > 1: @@ -1364,17 +1365,17 @@ def returnField(obj, field): info.cleanDGinfo(dataGroup) info.fid.close() # close file - if convertAfterRead and not compression: + if convert_after_read and not compression: self._noDataLoading = False - self._convertAllChannel4() + self._convert_all_channel_4() # print( 'Finished in ' + str( time.clock() - inttime ) , file=stderr) - def _getChannelData4(self, channelName, raw_data=False): + def _get_channel_data_4(self, channel_name, raw_data=False): """Returns channel numpy array Parameters ---------------- - channelName : str + channel_name : str channel name raw_data: bool flag to return non converted data @@ -1388,28 +1389,29 @@ def _getChannelData4(self, channelName, raw_data=False): ------ This method is the safest to get channel data as numpy array from 'data' dict key might contain raw data """ - if channelName in self: - vect = self.getChannel(channelName)[dataField] + if channel_name in self: + vect = self.get_channel(channel_name)[dataField] if vect is None: # noDataLoading reading argument flag activated if self.info.fid is None or (self.info.fid is not None and self.info.fid.closed): - (self.info.fid, self.info.fileName, self.info.zipfile) = _open_MDF(self.fileName) - self.read4(fileName=None, info=None, channelList=[channelName], convertAfterRead=False) + (self.info.fid, self.info.fileName, self.info.zipfile) = _open_mdf(self.fileName) + self.read4(file_name=None, info=None, channel_list=[channel_name], convert_after_read=False) if not raw_data: - return self._convertChannelData4(self.getChannel(channelName), - channelName, self.convert_tables)[channelName] + return self._convert_channel_data_4(self.get_channel(channel_name), channel_name, + self.convert_tables)[channel_name] else: - return self.getChannel(channelName)[dataField] + return self.get_channel(channel_name)[dataField] else: return None - def _convertChannelData4(self, channel, channelName, convert_tables, multiProc=False, Q=None): + @staticmethod + def _convert_channel_data_4(channel, channel_name, convert_tables, multiProc=False, Q=None): """converts specific channel from raw to physical data according to CCBlock information Parameters ---------------- channel : channel class channel4 object - channelName : str + channel_name : str name of channel convert_tables : bool activates computation intensive loops for conversion with tables. Default is False @@ -1421,12 +1423,13 @@ def _convertChannelData4(self, channel, channelName, convert_tables, multiProc=F Returns ----------- dict - returns dict with channelName key containing numpy array converted to physical values according to conversion type + returns dict with channelName key containing numpy array converted to physical values according to + conversion type """ if channel[dataField] is None: vect = channel[dataField] else: - if isinstance(channel[dataField], compressed_data): + if isinstance(channel[dataField], CompressedData): vect = channel[dataField].decompression() # uncompressed blosc data else: vect = channel[dataField][:] # to have bcolz uncompressed data @@ -1435,66 +1438,67 @@ def _convertChannelData4(self, channel, channelName, convert_tables, multiProc=F conversion_type = channel[conversionField]['type'] conversion_parameter = channel[conversionField]['parameters'] if conversion_type == 1 and not text_type: - vect = linearConv(vect, conversion_parameter['cc_val']) + vect = _linear_conversion(vect, conversion_parameter['cc_val']) elif conversion_type == 2 and not text_type: - vect = rationalConv(vect, conversion_parameter['cc_val']) + vect = _rational_conversion(vect, conversion_parameter['cc_val']) elif conversion_type == 3 and not text_type: - vect = formulaConv(vect, conversion_parameter['cc_ref']['Comment']) + vect = _formula_conversion(vect, conversion_parameter['cc_ref']['Comment']) elif conversion_type == 4 and not text_type: - vect = valueToValueTableWInterpConv(vect, conversion_parameter['cc_val']) + vect = _value_to_value_table_with_interpolation_conversion(vect, conversion_parameter['cc_val']) elif conversion_type == 5 and not text_type: - vect = valueToValueTableWOInterpConv(vect, conversion_parameter['cc_val']) + vect = _value_to_value_table_without_interpolation_conversion(vect, conversion_parameter['cc_val']) elif conversion_type == 6 and not text_type and convert_tables: - vect = valueRangeToValueTableConv(vect, conversion_parameter['cc_val']) + vect = _value_range_to_value_table_conversion(vect, conversion_parameter['cc_val']) elif conversion_type == 7 and not text_type and convert_tables: - vect = valueToTextConv(vect, conversion_parameter['cc_val'], conversion_parameter['cc_ref']) + vect = _value_to_text_conversion(vect, conversion_parameter['cc_val'], conversion_parameter['cc_ref']) elif conversion_type == 8 and not text_type and convert_tables: - vect = valueRangeToTextConv(vect, conversion_parameter['cc_val'], conversion_parameter['cc_ref']) + vect = _value_range_to_text_conversion(vect, conversion_parameter['cc_val'], + conversion_parameter['cc_ref']) elif conversion_type == 9 and text_type and convert_tables: - vect = textToValueConv(vect, conversion_parameter['cc_val'], conversion_parameter['cc_ref']) + vect = _text_to_value_conversion(vect, conversion_parameter['cc_val'], conversion_parameter['cc_ref']) elif conversion_type == 10 and text_type and convert_tables: - vect = textToTextConv(vect, conversion_parameter['cc_ref']) - L = {} - L[channelName] = vect + vect = _text_to_text_conversion(vect, conversion_parameter['cc_ref']) + L = dict() + L[channel_name] = vect if multiProc: Q.put(L) else: return L - def _convertChannel4(self, channelName): + def _convert_channel_4(self, channel_name): """converts specific channel from raw to physical data according to CCBlock information Parameters ---------------- - channelName : str + channel_name : str Name of channel """ - self.setChannelData(channelName, self._getChannelData4(channelName)) - self.remove_channel_conversion(channelName) + self.set_channel_data(channel_name, self._get_channel_data_4(channel_name)) + self.remove_channel_conversion(channel_name) - def _convertAllChannel4(self): + def _convert_all_channel_4(self): """Converts all channels from raw data to converted data according to CCBlock information Converted data will take more memory. """ if self._noDataLoading: # no data loaded, load everything - self.read4(self.fileName, convertAfterRead=True) + self.read4(self.fileName, convert_after_read=True) else: if self.multiProc is False: - [self._convertChannel4(channelName) for channelName in self] + [self._convert_channel_4(channelName) for channelName in self] else: # multiprocessing proc = [] Q = Queue() L = {} for channelName in self: - channel = self.getChannel(channelName) + channel = self.get_channel(channelName) if 'conversion' in channel: - conversion = self.getChannelConversion(channelName) + conversion = self.get_channel_conversion(channelName) if conversion['type'] in (1, 2): # more time in multi proc - self._convertChannel4(channelName) + self._convert_channel_4(channelName) else: - proc.append(Process(target=self._convertChannelData4, - args=(channel, channelName, self.convert_tables, True, Q))) + proc.append(Process(target=self._convert_channel_data_4, + args=(channel, channelName, self.convert_tables, True, Q))) proc[-1].start() for p in proc: L.update(Q.get()) # concatenate results of processes in dict @@ -1503,15 +1507,15 @@ def _convertAllChannel4(self): del Q # free memory for channelName in self: if channelName in L: - self.setChannelData(channelName, L[channelName]) + self.set_channel_data(channelName, L[channelName]) self.remove_channel_conversion(channelName) - def write4(self, fileName=None, compression=False): + def write4(self, file_name=None, compression=False): """Writes simple mdf 4.1 file Parameters ---------------- - fileName : str, optional + file_name : str, optional Name of file If file name is not input, written file name will be the one read with appended '_new' string before extension compression : bool @@ -1523,12 +1527,12 @@ def write4(self, fileName=None, compression=False): """ # Starts first to write ID and header - if fileName is None: + if file_name is None: splitName = splitext(self.fileName) if splitName[-1] in ('.mfxz', '.MFXZ'): splitName[-1] = '.mfx' # do not resave in compressed file - fileName = ''.join([splitName[-2], '_New', splitName[-1]]) - fid = open(fileName, 'wb') # buffering should automatically be set + file_name = ''.join([splitName[-2], '_New', splitName[-1]]) + fid = open(file_name, 'wb') # buffering should automatically be set # IDBLock writing temp = IDBlock() temp.write(fid) @@ -1581,13 +1585,13 @@ def write4(self, fileName=None, compression=False): pointer = blocks['CG']['block_start'] + 104 blocks['CG']['CN'] = pointer # First CN link - master_channel_data = self._getChannelData4(masterChannel) + master_channel_data = self._get_channel_data_4(masterChannel) if master_channel_data is not None: cg_cycle_count = len(master_channel_data) - elif self._getChannelData4(self.masterChannelList[masterChannel][0]).shape[0] == 1: # classification + elif self._get_channel_data_4(self.masterChannelList[masterChannel][0]).shape[0] == 1: # classification cg_cycle_count = 1 elif master_channel_data not in self.masterChannelList[masterChannel]: - cg_cycle_count = len(self._getChannelData4(self.masterChannelList[masterChannel][0])) + cg_cycle_count = len(self._get_channel_data_4(self.masterChannelList[masterChannel][0])) warn('no master channel in datagroup {}'.format(dataGroup)) else: # no data in datagroup, skip @@ -1696,7 +1700,7 @@ def write4(self, fileName=None, compression=False): pointer = blocks[channel]['block_start'] + blocks[channel]['block_length'] # write channel unit - unit = self.getChannelUnit(channel) + unit = self.get_channel_unit(channel) if unit is not None and len(unit) > 0: blocks[nchannel]['Unit'] = pointer unit_name = '{}{}{}'.format(channel, '_U_', nchannel) @@ -1708,7 +1712,7 @@ def write4(self, fileName=None, compression=False): blocks[nchannel]['Unit'] = 0 # write channel description - desc = self.getChannelDesc(channel) + desc = self.get_channel_desc(channel) if desc is not None and len(desc) > 0: blocks[nchannel]['Comment'] = pointer desc_name = '{}{}{}'.format(channel, '_C_', nchannel) @@ -1768,21 +1772,21 @@ def apply_invalid_bit(self, channel_name): Name of channel """ try: - invalid_bit_pos = self.getInvalidBit(channel_name) + invalid_bit_pos = self.get_invalid_bit(channel_name) if isinstance(invalid_bit_pos, int): # invalid bit existing - mask = self._getChannelData4(self.getInvalidChannel(channel_name)) - data = self._getChannelData4(channel_name) + mask = self._get_channel_data_4(self.get_invalid_channel(channel_name)) + data = self._get_channel_data_4(channel_name) data = data.view(MaskedArray) invalid_byte = invalid_bit_pos >> 3 data.mask = bitwise_and(mask[:, invalid_byte], invalid_bit_pos & 0x07) - self.setChannelData(channel_name, data) + self.set_channel_data(channel_name, data) self._remove_channel_field(channel_name, invalidPosField) self._remove_channel_field(channel_name, invalidChannel) except KeyError: pass # warn('no invalid data found for channel ') - def getChannelName4(self, name, path): + def get_channel_name_4(self, name, path): """finds mdf channel name from name and path Parameters @@ -1792,9 +1796,9 @@ def getChannelName4(self, name, path): path: str source path or name, or channel group name, source name or path - Returns: + Returns ----------- - channel name + list of tuples (channel_name, (ndg, ncg, ncn)) """ output = [] @@ -1808,12 +1812,12 @@ def getChannelName4(self, name, path): return output -def linearConv(vect, cc_val): +def _linear_conversion(vector, cc_val): """ apply linear conversion to data Parameters ---------------- - vect : numpy 1D array + vector : numpy 1D array raw data to be converted to physical value cc_val : mdfinfo4.info4 conversion block ('CCBlock') dict @@ -1821,20 +1825,20 @@ def linearConv(vect, cc_val): ----------- converted data to physical value """ - P1 = cc_val[0] - P2 = cc_val[1] - if P2 == 1.0 and P1 in (0.0, -0.0): - return vect # keeps dtype probably more compact than float64 + p1 = cc_val[0] + p2 = cc_val[1] + if p2 == 1.0 and p1 in (0.0, -0.0): + return vector # keeps dtype probably more compact than float64 else: - return vect * P2 + P1 + return vector * p2 + p1 -def rationalConv(vect, cc_val): +def _rational_conversion(vector, cc_val): """ apply rational conversion to data Parameters ---------------- - vect : numpy 1D array + vector : numpy 1D array raw data to be converted to physical value cc_val : mdfinfo4.info4 conversion block ('CCBlock') dict @@ -1842,23 +1846,23 @@ def rationalConv(vect, cc_val): ----------- converted data to physical value """ - P1 = cc_val[0] - P2 = cc_val[1] - P3 = cc_val[2] - P4 = cc_val[3] - P5 = cc_val[4] - P6 = cc_val[5] - return (P1 * vect * vect + P2 * vect + P3) / (P4 * vect * vect + P5 * vect + P6) + p1 = cc_val[0] + p2 = cc_val[1] + p3 = cc_val[2] + p4 = cc_val[3] + p5 = cc_val[4] + p6 = cc_val[5] + return (p1 * vector * vector + p2 * vector + p3) / (p4 * vector * vector + p5 * vector + p6) -def formulaConv(vect, formula): +def _formula_conversion(vector, formula): """ apply formula conversion to data Parameters ---------------- - vect : numpy 1D array + vector : numpy 1D array raw data to be converted to physical value - cc_val : mdfinfo4.info4 conversion block ('CCBlock') dict + formula : mdfinfo4.info4 conversion block ('CCBlock') dict Returns ----------- @@ -1870,15 +1874,15 @@ def formulaConv(vect, formula): warn('Please install sympy to convert channel ') X = symbols('X') expr = lambdify(X, formula, modules='numpy', dummify=False) - return expr(vect) + return expr(vector) -def valueToValueTableWOInterpConv(vect, cc_val): +def _value_to_value_table_without_interpolation_conversion(vector, cc_val): """ apply value to value table without interpolation conversion to data Parameters ---------------- - vect : numpy 1D array + vector : numpy 1D array raw data to be converted to physical value cc_val : mdfinfo4.info4 conversion block ('CCBlock') dict @@ -1887,25 +1891,25 @@ def valueToValueTableWOInterpConv(vect, cc_val): converted data to physical value """ val_count = 2 * int(len(cc_val) / 2) - intVal = [cc_val[i] for i in range(0, val_count, 2)] - physVal = [cc_val[i] for i in range(1, val_count, 2)] - if all(diff(intVal) > 0): + int_val = [cc_val[i] for i in range(0, val_count, 2)] + phys_val = [cc_val[i] for i in range(1, val_count, 2)] + if all(diff(int_val) > 0): try: from scipy import interpolate - except: - raise ImportError('Please install scipy to convert channel') - f = interpolate.interp1d(intVal, physVal, kind='nearest', bounds_error=False) # nearest - return f(vect) # fill with Nan out of bounds while should be bounds + f = interpolate.interp1d(int_val, phys_val, kind='nearest', bounds_error=False) # nearest + return f(vector) # fill with Nan out of bounds while should be bounds + except ImportError: + warn('Please install scipy to convert channel') else: warn('X values for interpolation of channel are not increasing') -def valueToValueTableWInterpConv(vect, cc_val): +def _value_to_value_table_with_interpolation_conversion(vector, cc_val): """ apply value to value table with interpolation conversion to data Parameters ---------------- - vect : numpy 1D array + vector : numpy 1D array raw data to be converted to physical value cc_val : mdfinfo4.info4 conversion block ('CCBlock') dict @@ -1914,20 +1918,20 @@ def valueToValueTableWInterpConv(vect, cc_val): converted data to physical value """ val_count = 2 * int(len(cc_val) / 2) - intVal = [cc_val[i] for i in range(0, val_count, 2)] - physVal = [cc_val[i] for i in range(1, val_count, 2)] - if all(diff(intVal) > 0): - return interp(vect, intVal, physVal) # with interpolation + int_val = [cc_val[i] for i in range(0, val_count, 2)] + phys_val = [cc_val[i] for i in range(1, val_count, 2)] + if all(diff(int_val) > 0): + return interp(vector, int_val, phys_val) # with interpolation else: warn('X values for interpolation of channel are not increasing') -def valueRangeToValueTableConv(vect, cc_val): +def _value_range_to_value_table_conversion(vector, cc_val): """ apply value range to value table conversion to data Parameters ---------------- - vect : numpy 1D array + vector : numpy 1D array raw data to be converted to physical value cc_val : mdfinfo4.info4 conversion block ('CCBlock') dict @@ -1940,22 +1944,22 @@ def valueRangeToValueTableConv(vect, cc_val): key_max = [cc_val[i] for i in range(1, 3 * val_count + 1, 3)] value = [cc_val[i] for i in range(2, 3 * val_count + 1, 3)] # look up in range keys - for Lindex in range(len(vect)): + for lindex in range(len(vector)): key_index = 0 # default index if not found for i in range(val_count): - if key_min[i] < vect[Lindex] < key_max[i]: + if key_min[i] < vector[lindex] < key_max[i]: key_index = i break - vect[Lindex] = value[key_index] - return vect + vector[lindex] = value[key_index] + return vector -def valueToTextConv(vect, cc_val, cc_ref): +def _value_to_text_conversion(vector, cc_val, cc_ref): """ apply value to text conversion to data Parameters ---------------- - vect : numpy 1D array + vector : numpy 1D array raw data to be converted to physical value cc_val : cc_val from mdfinfo4.info4 conversion block ('CCBlock') dict cc_ref : cc_ref from mdfinfo4.info4 conversion block ('CCBlock') dict @@ -1965,7 +1969,7 @@ def valueToTextConv(vect, cc_val, cc_ref): converted data to physical value """ maxlen = max([len(ref) for ref in cc_ref]) - temp = empty(len(vect), dtype='U{}'.format(maxlen)) # initialize empty array with max length + temp = empty(len(vector), dtype='U{}'.format(maxlen)) # initialize empty array with max length # checks for scaling try: from sympy import lambdify, symbols @@ -1987,35 +1991,35 @@ def valueToTextConv(vect, cc_val, cc_ref): (PythonVersion < 3 and not isinstance(cc_ref[ref], unicode)): # identity, non conversion cc_ref[ref] = lambdify(X, 'X' , modules='numpy', dummify=False) - key_index = where(vect[0] == cc_val)[0] # look up for first value in vect + key_index = where(vector[0] == cc_val)[0] # look up for first value in vector if not len(key_index) == 0: # value corresponding in cc_val temp[0] = cc_ref[key_index[0]] else: # default value if callable(cc_ref[-1]): - temp[0] = cc_ref[-1](vect[0]) + temp[0] = cc_ref[-1](vector[0]) else: temp[0] = cc_ref[-1] - for Lindex in range(1, len(vect)): - if vect[Lindex] == vect[Lindex - 1]: # same value as before, no need to look further - temp[Lindex] = temp[Lindex - 1] + for lindex in range(1, len(vector)): + if vector[lindex] == vector[lindex - 1]: # same value as before, no need to look further + temp[lindex] = temp[lindex - 1] else: # value changed from previous step - key_index = where(vect[Lindex] == cc_val)[0] + key_index = where(vector[lindex] == cc_val)[0] if not len(key_index) == 0: # found match - temp[Lindex] = cc_ref[key_index[0]] + temp[lindex] = cc_ref[key_index[0]] else: # default if callable(cc_ref[-1]): - temp[Lindex] = cc_ref[-1](vect[Lindex]) + temp[lindex] = cc_ref[-1](vector[lindex]) else: - temp[Lindex] = cc_ref[-1] + temp[lindex] = cc_ref[-1] return asarray(temp) -def valueRangeToTextConv(vect, cc_val, cc_ref): +def _value_range_to_text_conversion(vector, cc_val, cc_ref): """ apply value range to text conversion to data Parameters ---------------- - vect : numpy 1D array + vector : numpy 1D array raw data to be converted to physical value cc_val : cc_val from mdfinfo4.info4 conversion block ('CCBlock') dict cc_ref : cc_ref from mdfinfo4.info4 conversion block ('CCBlock') dict @@ -2048,7 +2052,7 @@ def valueRangeToTextConv(vect, cc_val, cc_ref): # Otherwise a string # look up in range keys temp = [] - for value in vect: + for value in vector: key_index = val_count # default index if not found for i in range(val_count): if key_min[i] <= value <= key_max[i]: @@ -2062,12 +2066,12 @@ def valueRangeToTextConv(vect, cc_val, cc_ref): return asarray(temp) -def textToValueConv(vect, cc_val, cc_ref): +def _text_to_value_conversion(vector, cc_val, cc_ref): """ apply text to value conversion to data Parameters ---------------- - vect : numpy 1D array + vector : numpy 1D array raw data to be converted to physical value cc_val : cc_val from mdfinfo4.info4 conversion block ('CCBlock') dict cc_ref : cc_ref from mdfinfo4.info4 conversion block ('CCBlock') dict @@ -2078,22 +2082,22 @@ def textToValueConv(vect, cc_val, cc_ref): """ ref_count = len(cc_ref) temp = [] - for Lindex in range(len(vect)): + for Lindex in range(len(vector)): key_index = ref_count # default index if not found for i in range(ref_count): - if vect[Lindex] == cc_ref[i]: + if vector[Lindex] == cc_ref[i]: key_index = i break temp.append(cc_val[key_index]) return asarray(temp) -def textToTextConv(vect, cc_ref): +def _text_to_text_conversion(vector, cc_ref): """ apply text to text conversion to data Parameters ---------------- - vect : numpy 1D array + vector : numpy 1D array raw data to be converted to physical value cc_ref : cc_ref from mdfinfo4.info4 conversion block ('CCBlock') dict @@ -2102,11 +2106,11 @@ def textToTextConv(vect, cc_ref): converted data to physical value """ ref_count = len(cc_ref) - 2 - for Lindex in range(len(vect)): + for Lindex in range(len(vector)): key_index = ref_count + 1 # default index if not found for i in range(0, ref_count, 2): - if vect[Lindex] == cc_ref[i]: + if vector[Lindex] == cc_ref[i]: key_index = i break - vect[Lindex] = cc_ref[key_index] - return vect + vector[Lindex] = cc_ref[key_index] + return vector diff --git a/mdfreader/mdfinfo4.py b/mdfreader/mdfinfo4.py index 0a4d6d8..954c8e9 100644 --- a/mdfreader/mdfinfo4.py +++ b/mdfreader/mdfinfo4.py @@ -27,36 +27,36 @@ from xml.etree.ElementTree import Element, SubElement, \ tostring, register_namespace from lxml import objectify -from .mdf import _open_MDF, dataField, descriptionField, unitField, \ - masterField, masterTypeField, idField, _convertName +from .mdf import _open_mdf, dataField, descriptionField, unitField, \ + masterField, masterTypeField, idField, _convert_name PythonVersion = version_info PythonVersion = PythonVersion[0] # datatypes -LINK = '' in Type: - endian = Type[0] - Type = Type.strip('<>') - return unpack(endian+count*Type, value) + if '<' in data_type or '>' in data_type: + endian = data_type[0] + data_type = data_type.strip('<>') + return unpack(endian + count * data_type, value) else: - return unpack(count*Type, value) + return unpack(count * data_type, value) else: return None def _calculate_block_start(current_position): - """ converts pointer poistion into one being multiple of 8 + """ converts pointer position into one being multiple of 8 Parameters ---------------- @@ -223,12 +223,12 @@ class HDBlock(dict): """ reads Header block and save in class dict """ - def __init__(self, fid=None, pointer=64): + def __init__(self, fid=None): if fid is not None: self.read(fid) - def read(self, fid=None, pointer=64): - fid.seek(pointer) + def read(self, fid=None): + fid.seek(64) (self['id'], reserved, self['length'], @@ -264,13 +264,13 @@ def write(self, fid): # time in ns, timezone offset in min, time daylight offset in min, # time flags, time class, hd flags, reserved, start angle in radians # start distance in meters) - dataBytes = (b'##HD', 0, 104, 6, - self['DG'], self['FH'], 0, 0, 0, 0, - int(time.time()*1E9), - int(time.timezone/60), - int(time.daylight*60), - 2, 0, 0, b'\0', 0, 0) - fid.write(pack('<4sI2Q7Q2h3Bs2d', *dataBytes)) + data_bytes = (b'##HD', 0, 104, 6, + self['DG'], self['FH'], 0, 0, 0, 0, + int(time.time()*1E9), + int(time.timezone/60), + int(time.daylight*60), + 2, 0, 0, b'\0', 0, 0) + fid.write(pack('<4sI2Q7Q2h3Bs2d', *data_bytes)) class FHBlock(dict): @@ -308,13 +308,13 @@ def write(self, fid): # (No next FH, comment block pointer # time in ns, timezone offset in min, time daylight offest in min, # time flags, reserved) - dataBytes = (b'##FH', 0, 56, 2, - 0, self['MD'], - int(time.time()*1E9), - int(time.timezone/60), - int(time.daylight*60), - 2, b'\0' * 3) - fid.write(pack('<4sI2Q3Q2hB3s', *dataBytes)) + data_bytes = (b'##FH', 0, 56, 2, + 0, self['MD'], + int(time.time()*1E9), + int(time.timezone/60), + int(time.daylight*60), + 2, b'\0' * 3) + fid.write(pack('<4sI2Q3Q2hB3s', *data_bytes)) class CHBlock(dict): @@ -324,21 +324,21 @@ class CHBlock(dict): def __init__(self, fid, pointer): # block header - self.update(_loadHeader(fid, pointer)) + self.update(_load_header(fid, pointer)) # Channel hierarchy block (self['ch_ch_next'], self['ch_ch_first'], self['ch_tx_name'], self['ch_md_comment']) = unpack('<4Q', fid.read(32)) - nLinks = self['link_count'] - 4 - self['ch_element'] = unpack('<{}Q'.format(nLinks), - fid.read(nLinks * 8)) + n_links = self['link_count'] - 4 + self['ch_element'] = unpack('<{}Q'.format(n_links), + fid.read(n_links * 8)) (self['ch_element_count'], self['ch_type'], ch_reserved) = unpack(' 0: self['cn_at_reference'] = \ - _mdfblockread(kargs['fid'], LINK, self['cn_attachment_count']) + _mdf_block_read(kargs['fid'], _LINK, self['cn_attachment_count']) self['attachment'] = {} if self['cn_attachment_count'] > 1: for at in range(self['cn_attachment_count']): @@ -748,7 +748,7 @@ def readCN(self, **kargs): self['attachment'][0] = \ ATBlock(kargs['fid'], self['cn_at_reference']) if self['link_count'] > (8 + self['cn_attachment_count']): - self['cn_default_x'] = _mdfblockread(kargs['fid'], LINK, 3) + self['cn_default_x'] = _mdf_block_read(kargs['fid'], _LINK, 3) else: self['cn_default_x'] = None if self['cn_md_comment']: # comments exist @@ -773,7 +773,7 @@ def readCN(self, **kargs): def write(self, fid): # write block header # fid.seek(self['block_start']) - # no attachement and default X + # no attachment and default X # link section # (Next channel block pointer, composition of channel pointer, # TXBlock pointer for channel name, source SIBlock pointer, @@ -786,15 +786,15 @@ def write(self, fid): # precision, reserved, attachments count, # val range min, val range max, val limit min, val limit max, # val limit ext min, val limit ext max) - dataBytes = (b'##CN', 0, 160, 8, - self['CN'], self['Composition'], self['TX'], 0, 0, 0, self['Unit'], self['Comment'], - self['cn_type'], self['cn_sync_type'], - self['cn_data_type'], self['cn_bit_offset'], - self['cn_byte_offset'], self['cn_bit_count'], - self['cn_flags'], 0, 0, 0, 0, - self['cn_val_range_min'], self['cn_val_range_max'], - 0, 0, 0, 0) - fid.write(pack('<4sI2Q8Q4B4I2BH6d', *dataBytes)) + data_bytes = (b'##CN', 0, 160, 8, + self['CN'], self['Composition'], self['TX'], 0, 0, 0, self['Unit'], self['Comment'], + self['cn_type'], self['cn_sync_type'], + self['cn_data_type'], self['cn_bit_offset'], + self['cn_byte_offset'], self['cn_bit_count'], + self['cn_flags'], 0, 0, 0, 0, + self['cn_val_range_min'], self['cn_val_range_max'], + 0, 0, 0, 0) + fid.write(pack('<4sI2Q8Q4B4I2BH6d', *data_bytes)) class CCBlock(dict): @@ -814,10 +814,9 @@ def readCC(self, fid, pointer): self['cc_tx_name'], self['cc_md_unit'], self['cc_md_comment'], - self['cc_cc_inverse']) = CCStruct1.unpack(fid.read(56)) + self['cc_cc_inverse']) = _CCStruct1.unpack(fid.read(56)) if self['link_count'] - 4 > 0: # can be no links for cc_ref - self['cc_ref'] = _mdfblockread(fid, LINK, - self['link_count'] - 4) + self['cc_ref'] = _mdf_block_read(fid, _LINK, self['link_count'] - 4) # data section (self['cc_type'], self['cc_precision'], @@ -825,9 +824,9 @@ def readCC(self, fid, pointer): self['cc_ref_count'], self['cc_val_count'], self['cc_phy_range_min'], - self['cc_phy_range_max']) = CCStruct2.unpack(fid.read(24)) + self['cc_phy_range_max']) = _CCStruct2.unpack(fid.read(24)) if self['cc_val_count']: - self['cc_val'] = _mdfblockread(fid, REAL, self['cc_val_count']) + self['cc_val'] = _mdf_block_read(fid, _REAL, self['cc_val_count']) if self['cc_type'] == 3: # reads Algebraic formula pointer = self['cc_ref'] self['cc_ref'] = {} @@ -839,13 +838,13 @@ def readCC(self, fid, pointer): for i in range(self['cc_ref_count']): fid.seek(self['cc_ref'][i]) # find if TX/MD or another CCBlock - ID = unpack('4s', fid.read(4))[0] + identifier = unpack('4s', fid.read(4))[0] # for algebraic formulae - if ID in ('##TX', '##MD', b'##TX', b'##MD'): + if identifier in ('##TX', '##MD', b'##TX', b'##MD'): temp = CommentBlock() temp.readCM(fid=fid, pointer=self['cc_ref'][i]) self['cc_ref'][i] = temp['Comment'] - elif ID in ('##CC', b'##CC'): # for table conversion + elif identifier in ('##CC', b'##CC'): # for table conversion # much more complicated nesting conversions !!! cc = CCBlock() cc.readCC(fid, self['cc_ref'][i]) @@ -875,7 +874,7 @@ def read(self, fid, pointer): (self['id'], reserved, self['length'], - self['link_count']) = HeaderStruct.unpack(fid.read(24)) + self['link_count']) = _HeaderStruct.unpack(fid.read(24)) self['pointer'] = pointer # reads data section fid.seek(pointer + 24 + self['link_count'] * 8) @@ -885,7 +884,7 @@ def read(self, fid, pointer): self['ca_flags'], self['ca_byte_offset_base'], self['ca_invalid_bit_pos_base']) = unpack('2BHIiI', fid.read(16)) - self['ca_dim_size'] = _mdfblockread(fid, UINT64, self['ca_ndim']) + self['ca_dim_size'] = _mdf_block_read(fid, _UINT64, self['ca_ndim']) try: # more than one dimension, processing dict self['SNd'] = 0 self['PNd'] = 1 @@ -897,33 +896,33 @@ def read(self, fid, pointer): self['PNd'] = self['SNd'] if 1 << 5 & self['ca_flags']: # bit5 self['ca_axis_value'] = \ - _mdfblockread(fid, REAL, self['SNd']) + _mdf_block_read(fid, _REAL, self['SNd']) if self['ca_storage'] >= 1: self['ca_cycle_count'] = \ - _mdfblockread(fid, UINT64, self['PNd']) + _mdf_block_read(fid, _UINT64, self['PNd']) # Channel Conversion block : Links fid.seek(pointer + 24) # point to CN for array of structures or CA for array of array - self['ca_composition'] = _mdfblockread(fid, LINK, 1) + self['ca_composition'] = _mdf_block_read(fid, _LINK, 1) if self['ca_storage'] == 2: - self['ca_data'] = _mdfblockread(fid, LINK, self['PNd']) + self['ca_data'] = _mdf_block_read(fid, _LINK, self['PNd']) if 1 << 0 & self['ca_flags']: # bit 0 self['ca_dynamic_size'] = \ - _mdfblockread(fid, LINK, self['ca_ndim'] * 3) + _mdf_block_read(fid, _LINK, self['ca_ndim'] * 3) if 1 << 1 & self['ca_flags']: # bit 1 self['ca_input_quantity'] = \ - _mdfblockread(fid, LINK, self['ca_ndim'] * 3) + _mdf_block_read(fid, _LINK, self['ca_ndim'] * 3) if 1 << 2 & self['ca_flags']: # bit 2 self['ca_output_quantity'] = \ - _mdfblockread(fid, LINK, 3) + _mdf_block_read(fid, _LINK, 3) if 1 << 3 & self['ca_flags']: # bit 3 - self['ca_comparison_quantity'] = _mdfblockread(fid, LINK, 3) + self['ca_comparison_quantity'] = _mdf_block_read(fid, _LINK, 3) if 1 << 4 & self['ca_flags']: # bit 4 self['ca_cc_axis_conversion'] = \ - _mdfblockread(fid, LINK, self['ca_ndim']) + _mdf_block_read(fid, _LINK, self['ca_ndim']) if 1 << 4 & self['ca_flags'] and not 1 << 5 & self['ca_flags']: # bit 4 and 5 - self['ca_axis'] = _mdfblockread(fid, LINK, self['ca_ndim'] * 3) + self['ca_axis'] = _mdf_block_read(fid, _LINK, self['ca_ndim'] * 3) # nested arrays if self['ca_composition']: self['CABlock'] = CABlock() @@ -935,10 +934,10 @@ def load(self, byte_offset_base): def write(self, fid): # default CN template - dataBytes = (b'##CA', 0, 48 + 8 * self['ndim'], 1, - 0, - 0, 0, self['ndim'], 0, self['byte_offset_base'], 0) - fid.write(pack('<4sI2Q1Q2BHIiI', *dataBytes)) + data_bytes = (b'##CA', 0, 48 + 8 * self['ndim'], 1, + 0, + 0, 0, self['ndim'], 0, self['byte_offset_base'], 0) + fid.write(pack('<4sI2Q1Q2BHIiI', *data_bytes)) fid.write(pack('<{}Q'.format(self['ndim']), *self['ndim_size'])) @@ -986,7 +985,7 @@ def __init__(self, fid, pointer): (self['id'], reserved, self['length'], - self['link_count']) = HeaderStruct.unpack(fid.read(24)) + self['link_count']) = _HeaderStruct.unpack(fid.read(24)) # data section fid.seek(pointer + self['length'] - 32) (self['ev_type'], @@ -1007,7 +1006,7 @@ def __init__(self, fid, pointer): self['ev_ev_range'], self['ev_tx_name'], self['ev_md_comment']) = unpack('<5Q', fid.read(40)) - self['ev_scope'] = _mdfblockread(fid, LINK, self['ev_scope_count']) + self['ev_scope'] = _mdf_block_read(fid, _LINK, self['ev_scope_count']) # post treatment try: self['ev_cause'] = ev_cause[self['ev_cause']] @@ -1015,7 +1014,7 @@ def __init__(self, fid, pointer): warn('unexpected ev cause') if self['ev_attachment_count'] > 0: self['ev_at_reference'] = \ - _mdfblockread(fid, LINK, self['ev_attachment_count']) + _mdf_block_read(fid, _LINK, self['ev_attachment_count']) for at in range(self['ev_attachment_count']): self['attachment'][at] = \ ATBlock(fid, self['ev_at_reference'][at]) @@ -1046,7 +1045,7 @@ def __init__(self, fid, pointer): self['sr_interval'], self['sr_sync_type'], self['sr_flags'], - sr_reserved) = SRStruct.unpack(fid.read(64)) + sr_reserved) = _SRStruct.unpack(fid.read(64)) class SIBlock(dict): @@ -1068,7 +1067,7 @@ def readSI(self, fid, pointer): self['si_type'], self['si_bus_type'], self['si_flags'], - si_reserved) = SIStruct.unpack(fid.read(56)) + si_reserved) = _SIStruct.unpack(fid.read(56)) try: self['si_type'] = si_type[self['si_type']] except KeyError: @@ -1093,7 +1092,7 @@ def load(self, record_byte_offset, nRecords, pointer): self['end_position'] = _calculate_block_start(self['pointer'] + self['datablocks_length']) def write(self, fid, data): - fid.write(HeaderStruct.pack(b'##DT', 0, self['datablocks_length'], 0)) + fid.write(_HeaderStruct.pack(b'##DT', 0, self['datablocks_length'], 0)) # dumps data fid.write(data) return self['end_position'] @@ -1128,8 +1127,8 @@ def write(self, fid, chunks, position): for counter in range(1, number_DL): (nrecord_chunk, chunk_size) = chunks[counter] dl_offset[counter] = dl_offset[counter - 1] + chunk_size - dataBytes = (b'##DL', 0, self['block_length'], number_DL + 1, 0) - fid.write(pack('<4sI3Q'.format(number_DL, number_DL), *dataBytes)) + data_bytes = (b'##DL', 0, self['block_length'], number_DL + 1, 0) + fid.write(pack('<4sI3Q'.format(number_DL, number_DL), *data_bytes)) fid.write(pack('{0}Q'.format(number_DL), *zeros(shape=number_DL, dtype=' 1: for at in range(self['CN'][dg][cg][cn]['cn_attachment_count']): - self['CN'][dg][cg][cn]['attachment'][at].update(self.readATBlock(fid, self['CN'][dg][cg][cn]['cn_at_reference'][at])) + self['CN'][dg][cg][cn]['attachment'][at].update( + self.read_ATBlock(fid, self['CN'][dg][cg][cn]['cn_at_reference'][at])) elif self['CN'][dg][cg][cn]['cn_attachment_count'] == 1: self['CN'][dg][cg][cn]['attachment'][0].update( - self.readATBlock(fid, self['CN'][dg][cg][cn]['cn_at_reference'])) + self.read_ATBlock(fid, self['CN'][dg][cg][cn]['cn_at_reference'])) while self['CN'][dg][cg][cn]['cn_cn_next']: cn = cn + 1 self['CN'][dg][cg][cn] = {} temp = CNBlock() - temp.readCN(fid=fid, pointer=self['CN'][dg][cg][cn - 1]['cn_cn_next']) + temp.read_CN(fid=fid, pointer=self['CN'][dg][cg][cn - 1]['cn_cn_next']) self['CN'][dg][cg][cn].update(temp) # check for MLSD if self['CN'][dg][cg][cn]['cn_type'] == 5: @@ -1613,7 +1613,7 @@ def readCNBlock(self, fid, dg, cg, channelNameList=False, minimal=0): # reads Channel Conversion Block self['CC'][dg][cg][cn] = CCBlock() self['CC'][dg][cg][cn].readCC(fid, self['CN'][dg][cg][cn]['cn_cc_conversion']) - if not channelNameList: + if not channel_name_list: if not minimal: # reads Channel Source Information temp = SIBlock() @@ -1625,7 +1625,8 @@ def readCNBlock(self, fid, dg, cg, channelNameList=False, minimal=0): # keep original non unique channel name self['CN'][dg][cg][cn]['orig_name'] = self['CN'][dg][cg][cn]['name'] # check if already existing channel name - self['CN'][dg][cg][cn]['name'] = self._unique(fid, self['CN'][dg][cg][cn]['name'], dg, cg, cn) + self['CN'][dg][cg][cn]['name'] = \ + self._unique_channel_name(fid, self['CN'][dg][cg][cn]['name'], dg, cg, cn) if self['CN'][dg][cg][cn]['cn_type'] == 1 and PythonVersion < 3: # VLSD needs to rename and append records but with python 2.x impossible, # convert name to compatible python identifier @@ -1642,7 +1643,7 @@ def readCNBlock(self, fid, dg, cg, channelNameList=False, minimal=0): elif id in ('##CN', b'##CN'): self['CN'][dg][cg][cn]['CN'] = {} temp = CNBlock() - temp.readCN(fid=fid, pointer=self['CN'][dg][cg][cn]['cn_composition']) + temp.read_CN(fid=fid, pointer=self['CN'][dg][cg][cn]['cn_composition']) self['CN'][dg][cg][cn]['CN'].update(temp) else: raise('unknown channel composition') @@ -1651,12 +1652,13 @@ def readCNBlock(self, fid, dg, cg, channelNameList=False, minimal=0): # reads Attachment Block if self['CN'][dg][cg][cn]['cn_attachment_count'] > 1: for at in range(self['CN'][dg][cg][cn]['cn_attachment_count']): - self['CN'][dg][cg][cn]['attachment'][at].update(self.readATBlock(fid, self['CN'][dg][cg][cn]['cn_at_reference'][at])) + self['CN'][dg][cg][cn]['attachment'][at].update( + self.read_ATBlock(fid, self['CN'][dg][cg][cn]['cn_at_reference'][at])) elif self['CN'][dg][cg][cn]['cn_attachment_count'] == 1: self['CN'][dg][cg][cn]['attachment'][0].update( - self.readATBlock(fid, self['CN'][dg][cg][cn]['cn_at_reference'])) + self.read_ATBlock(fid, self['CN'][dg][cg][cn]['cn_at_reference'])) - MLSDChannels = self.readComposition(fid, dg, cg, MLSDChannels) + MLSDChannels = self.read_composition(fid, dg, cg, MLSDChannels) if MLSDChannels: self['MLSD'] = {} @@ -1694,7 +1696,7 @@ def cleanDGinfo(self, dg): except KeyError: pass - def readComposition(self, fid, dg, cg, MLSDChannels): + def read_composition(self, fid, dg, cg, MLSD_channels): """check for composition of channels, arrays or structures Parameters @@ -1705,7 +1707,7 @@ def readComposition(self, fid, dg, cg, MLSDChannels): data group number cg : int channel group number in data group - MLSDChannels : list of int + MLSD_channels : list of int channel numbers Returns @@ -1719,41 +1721,41 @@ def readComposition(self, fid, dg, cg, MLSDChannels): ID = unpack('4s', fid.read(4))[0] if ID in ('##CN', b'##CN'): # Structures self['CN'][dg][cg][chan] = CNBlock() - self['CN'][dg][cg][chan].readCN(fid=fid, - pointer=self['CN'][dg][cg][cn]['cn_composition']) + self['CN'][dg][cg][chan].read_CN(fid=fid, pointer=self['CN'][dg][cg][cn]['cn_composition']) # keep original non unique channel name self['CN'][dg][cg][chan]['orig_name'] = self['CN'][dg][cg][chan]['name'] # make sure channel name is unique - self['CN'][dg][cg][chan]['name'] = self._unique(fid, self['CN'][dg][cg][chan]['name'], dg, cg, cn) + self['CN'][dg][cg][chan]['name'] = \ + self._unique_channel_name(fid, self['CN'][dg][cg][chan]['name'], dg, cg, cn) self['CC'][dg][cg][chan] = CCBlock() self['CC'][dg][cg][chan].readCC(fid, self['CN'][dg][cg][chan]['cn_cc_conversion']) if self['CN'][dg][cg][chan]['cn_type'] == 5: - MLSDChannels.append(chan) + MLSD_channels.append(chan) while self['CN'][dg][cg][chan]['cn_cn_next']: chan += 1 self['CN'][dg][cg][chan] = CNBlock() - self['CN'][dg][cg][chan].readCN(fid=fid, - pointer=self['CN'][dg][cg][chan - 1]['cn_cn_next']) + self['CN'][dg][cg][chan].read_CN(fid=fid, pointer=self['CN'][dg][cg][chan - 1]['cn_cn_next']) # keep original non unique channel name self['CN'][dg][cg][chan]['orig_name'] = self['CN'][dg][cg][chan]['name'] # make sure channel name is unique - self['CN'][dg][cg][chan]['name'] = self._unique(fid, self['CN'][dg][cg][chan]['name'], dg, cg, cn) + self['CN'][dg][cg][chan]['name'] = \ + self._unique_channel_name(fid, self['CN'][dg][cg][chan]['name'], dg, cg, cn) self['CC'][dg][cg][chan] = CCBlock() self['CC'][dg][cg][chan].readCC(fid, self['CN'][dg][cg][chan]['cn_cc_conversion']) if self['CN'][dg][cg][chan]['cn_type'] == 5: - MLSDChannels.append(chan) + MLSD_channels.append(chan) # makes the channel virtual self['CN'][dg][cg][cn]['cn_type'] = 6 elif ID in ('##CA', b'##CA'): # arrays pass else: warn('unknown channel composition') - return MLSDChannels + return MLSD_channels - def readSRBlock(self, fid, pointer): + def read_SRBlock(self, fid, pointer): """reads Sample Reduction Blocks Parameters @@ -1769,14 +1771,14 @@ def readSRBlock(self, fid, pointer): """ if pointer > 0: sr = 0 - srBlocks = {} - srBlocks[0] = SRBlock(fid, pointer) - while srBlocks[sr]['sr_sr_next'] > 0: + sr_blocks = dict() + sr_blocks[0] = SRBlock(fid, pointer) + while sr_blocks[sr]['sr_sr_next'] > 0: sr += 1 - srBlocks[sr] = SRBlock(fid, srBlocks[sr - 1]['sr_sr_next']) - return srBlocks + sr_blocks[sr] = SRBlock(fid, sr_blocks[sr - 1]['sr_sr_next']) + return sr_blocks - def readATBlock(selfself, fid, pointer): + def read_ATBlock(self, fid, pointer): """reads Attachment blocks Parameters @@ -1792,51 +1794,52 @@ def readATBlock(selfself, fid, pointer): """ if pointer > 0: at = 0 - atBlocks = {} + at_blocks = {} if type(pointer) in (tuple, list): pointer = pointer[0] - atBlocks[0] = ATBlock(fid, pointer) - while atBlocks[at]['at_at_next'] > 0: + at_blocks[0] = ATBlock(fid, pointer) + while at_blocks[at]['at_at_next'] > 0: at += 1 - atBlocks[at] = (ATBlock(fid, atBlocks[at - 1]['at_at_next'])) - return atBlocks + at_blocks[at] = (ATBlock(fid, at_blocks[at - 1]['at_at_next'])) + return at_blocks - def listChannels4(self, fileName=None, fid=None): + def list_channels_4(self, file_name=None, fid=None): """ Read MDF file and extract its complete structure Parameters ---------------- - fileName : str + file_name : str file name + fid Returns ----------- list of channel names contained in file """ - if fileName is not None: - self.fileName = fileName + if file_name is not None: + self.fileName = file_name # Open file - if fid is None and fileName is not None: + if fid is None and file_name is not None: # Open file - (fid, fileName, zipfile) = _open_MDF(self.fileName) - channelNameList = [] + (fid, file_name, zipfile) = _open_mdf(self.fileName) + channel_name_list = [] # reads Header HDBlock self['HD'].update(HDBlock(fid)) # reads Data Group, channel groups and channel Blocks # recursively but not the other metadata block - self.readDGBlock(fid, True) + self.read_DGBlock(fid, True) for dg in self['DG']: for cg in self['CG'][dg]: for cn in self['CN'][dg][cg]: - channelNameList.append(self['CN'][dg][cg][cn]['name']) + channel_name_list.append(self['CN'][dg][cg][cn]['name']) # CLose the file fid.close() - return channelNameList + return channel_name_list - def _unique(self, fid, name, dg, cg, cn): + def _unique_channel_name(self, fid, name, dg, cg, cn): """ generate unique channel name Parameters @@ -1931,7 +1934,7 @@ def unique_id(self, ndg, ncg, ncn): return (ndg, ncg, ncn), (cn, cs, cp), (gn, gs, gp) -def _generateDummyMDF4(info, channelList): +def _generate_dummy_mdf4(info, channel_list): """ computes MasterChannelList and dummy mdf dict from an info object Parameters @@ -1939,7 +1942,7 @@ def _generateDummyMDF4(info, channelList): info : info object information structure of file - channelList : list of str + channel_list : list of str channel list Returns @@ -1947,20 +1950,20 @@ def _generateDummyMDF4(info, channelList): a dict which keys are master channels in files with values a list of related channels of the raster """ MasterChannelList = {} - allChannelList = set() + all_channel_list = set() mdfdict = {} for dg in info['DG']: master = '' mastertype = 0 - ChannelNamesByDG = set() + channel_names_by_dg = set() for cg in info['CG'][dg]: - channelNameList = [] + channel_name_list = [] for cn in info['CN'][dg][cg]: if info['CN'][dg][cg][cn]['cn_data_type'] == 13: for name in ('ms', 'minute', 'hour', 'day', 'month', 'year'): - channelNameList.append(name) - allChannelList.add(name) - ChannelNamesByDG.add(name) + channel_name_list.append(name) + all_channel_list.add(name) + channel_names_by_dg.add(name) mdfdict[name] = {} mdfdict[name][dataField] = None mdfdict[name][descriptionField] = name @@ -1968,9 +1971,9 @@ def _generateDummyMDF4(info, channelList): mdfdict[name][idField] = (dg, cg, cn) elif info['CN'][dg][cg][cn]['cn_data_type'] == 14: for name in ('ms', 'days'): - channelNameList.append(name) - allChannelList.add(name) - ChannelNamesByDG.add(name) + channel_name_list.append(name) + all_channel_list.add(name) + channel_names_by_dg.add(name) mdfdict[name] = {} mdfdict[name][dataField] = None mdfdict[name][descriptionField] = name @@ -1978,13 +1981,13 @@ def _generateDummyMDF4(info, channelList): mdfdict[name][idField] = (dg, cg, cn) else: name = info['CN'][dg][cg][cn]['name'] - if name in ChannelNamesByDG: + if name in channel_names_by_dg: name = u'{0}_{1}_{2}_{3}'.format(name, dg, cg, cn) - elif name in allChannelList: + elif name in all_channel_list: name = u'{0}_{1}'.format(name, dg) - if channelList is None or name in channelList: - channelNameList.append(name) - allChannelList.add(name) + if channel_list is None or name in channel_list: + channel_name_list.append(name) + all_channel_list.add(name) # create mdf channel mdfdict[name] = {} mdfdict[name][dataField] = None @@ -2003,8 +2006,8 @@ def _generateDummyMDF4(info, channelList): # master channel of cg master = name mastertype = info['CN'][dg][cg][cn]['cn_sync_type'] - for chan in channelNameList: + for chan in channel_name_list: mdfdict[chan][masterField] = master mdfdict[chan][masterTypeField] = mastertype - MasterChannelList[master] = channelNameList + MasterChannelList[master] = channel_name_list return MasterChannelList, mdfdict diff --git a/mdfreader/mdfreader.py b/mdfreader/mdfreader.py index 366a8a9..34052ac 100644 --- a/mdfreader/mdfreader.py +++ b/mdfreader/mdfreader.py @@ -47,10 +47,10 @@ from numpy import nan, datetime64, array, searchsorted, clip from numpy.ma import MaskedArray from .mdf3reader import mdf3 -from .mdf4reader import mdf4 -from .mdf import _open_MDF, dataField, descriptionField, unitField, masterField, masterTypeField +from .mdf4reader import Mdf4 +from .mdf import _open_mdf, dataField, descriptionField, unitField, masterField, masterTypeField from .mdfinfo3 import info3, _generateDummyMDF3 -from .mdfinfo4 import info4, _generateDummyMDF4 +from .mdfinfo4 import Info4, _generate_dummy_mdf4 PythonVersion = version_info PythonVersion = PythonVersion[0] @@ -182,7 +182,7 @@ def readinfo(self, fileName=None, fid=None, minimal=0): # Open file if self.fid is None or (self.fid is not None and self.fid.closed): - (self.fid, self.fileName, self.zipfile) = _open_MDF(self.fileName) + (self.fid, self.fileName, self.zipfile) = _open_mdf(self.fileName) # read Identifier block self.fid.seek(28) @@ -191,7 +191,7 @@ def readinfo(self, fileName=None, fid=None, minimal=0): if self.mdfversion < 400: # up to version 3.x not compatible with version 4.x self.update(info3(None, self.fid, self.filterChannelNames)) else: # MDF version 4.x - self.update(info4(None, self.fid, minimal)) + self.update(Info4(None, self.fid, minimal)) if self.zipfile and fid is None: # not from mdfreader.read() remove(self.fileName) @@ -213,7 +213,7 @@ def listChannels(self, fileName=None): if self.fileName is None or fileName is not None: self.fileName = fileName # Open file - (self.fid, self.fileName, zipfile) = _open_MDF(self.fileName) + (self.fid, self.fileName, zipfile) = _open_mdf(self.fileName) # read Identifier block self.fid.seek(28) MDFVersionNumber = unpack(' 1: # Not yet resampled or only 1 datagroup # create master channel if not proposed if masterChannel is None and masterData is not None: - self.add_channel(0, masterChannelName, - masterData, - masterChannelName, - master_type=self.getChannelMasterType(master), - unit=self.getChannelUnit(master), - description=self.getChannelDesc(master), - conversion=None) + self.add_channel(masterChannelName, masterData, masterChannelName, + master_type=self.get_channel_master_type(master), unit=self.get_channel_unit(master), + description=self.get_channel_desc(master), conversion=None) # Interpolate channels timevect = [] @@ -654,21 +645,22 @@ def interpolate(new_x, x, y): for Name in list(self.keys()): try: if Name not in list(self.masterChannelList.keys()): # not a master channel - timevect = self.getChannelData(self.getChannelMaster(Name)) + timevect = self.getChannelData(self.get_channel_master(Name)) if not self.getChannelData(Name).dtype.kind in ('S', 'U', 'V'): # if channel not array of string - self.setChannelData(Name, interpolate(masterData, timevect, self.getChannelData(Name))) - self.setChannelMaster(Name, masterChannelName) - self.setChannelMasterType(Name, self.getChannelMasterType(master)) + self.set_channel_data(Name, + interpolate(masterData, timevect, self.getChannelData(Name))) + self.set_channel_master(Name, masterChannelName) + self.set_channel_master_type(Name, self.get_channel_master_type(master)) self.remove_channel_conversion(Name) else: # can not interpolate strings, remove channel containing string self.remove_channel(Name) except: if timevect is not None and len(timevect) != len(self.getChannelData(Name)): warn('{} and master channel {} do not have same length'. - format(Name, self.getChannelMaster(Name))) + format(Name, self.get_channel_master(Name))) elif not all(diff(timevect) > 0): - master = self.getChannelMaster(Name) + master = self.get_channel_master(Name) warn('{} has non regularly increasing master channel {}.\n' ' Faulty samples will be dropped in related data group'. format(Name, master)) @@ -684,10 +676,10 @@ def interpolate(new_x, x, y): masterData = self.getChannelData(list(self.masterChannelList.keys())[0]) masterData = arange(masterData[0], masterData[-1], samplingTime) for Name in list(self.keys()): - timevect = self.getChannelData(self.getChannelMaster(Name)) - self.setChannelData(Name, interpolate(masterData, timevect, self.getChannelData(Name))) - self.setChannelMaster(Name, masterChannelName) - self.setChannelMasterType(Name, self.getChannelMasterType(master)) + timevect = self.getChannelData(self.get_channel_master(Name)) + self.set_channel_data(Name, interpolate(masterData, timevect, self.getChannelData(Name))) + self.set_channel_master(Name, masterChannelName) + self.set_channel_master_type(Name, self.get_channel_master_type(master)) self.remove_channel_conversion(Name) elif samplingTime is None: warn('Already resampled') @@ -709,7 +701,7 @@ def _clean_uneven_master_data(self, master_channel_name): for channel in self.masterChannelList[master_channel_name]: data = self.getChannelData(channel).view(MaskedArray) data.mask = mask - self.setChannelData(channel, data.compressed()) + self.set_channel_data(channel, data.compressed()) def cut(self, begin=None, end=None): """ Cut data @@ -746,11 +738,11 @@ def cut(self, begin=None, end=None): if startIndex == endIndex: # empty array for channel in self.masterChannelList[master]: - self.setChannelData(channel, array([])) + self.set_channel_data(channel, array([])) else: for channel in self.masterChannelList[master]: data = self.getChannelData(channel) - self.setChannelData(channel, data[startIndex: endIndex]) + self.set_channel_data(channel, data[startIndex: endIndex]) def exportToCSV(self, filename=None, sampling=None): """Exports mdf data into CSV file @@ -787,7 +779,7 @@ def exportToCSV(self, filename=None, sampling=None): writer = csv.writer(f, dialect=csv.excel) for name in list(self.keys()): data = self.getChannelData(name) - unit = self.getChannelUnit(name) + unit = self.get_channel_unit(name) if data.dtype.kind not in ('S', 'U', 'V') \ and data.ndim <= 1: if name is bytes: @@ -797,7 +789,7 @@ def exportToCSV(self, filename=None, sampling=None): names.append(name.encode(encoding, 'replace')) except: names.append(name) - if self.getChannelUnit(name) is bytes: + if self.get_channel_unit(name) is bytes: units.append(unit.encode(encoding, 'ignore')) else: try: @@ -813,7 +805,7 @@ def exportToCSV(self, filename=None, sampling=None): if self.getChannelData(name).dtype.kind not in ('S', 'U', 'V') and self.getChannelData(name).ndim <= 1]) # writes channel names # writes units - writer.writerow([self.getChannelUnit(name) + writer.writerow([self.get_channel_unit(name) for name in list(self.keys()) if self.getChannelData(name).dtype.kind not in ('S', 'U', 'V') and self.getChannelData(name).ndim <= 1]) # writes units @@ -911,11 +903,11 @@ def setAttribute(f, name, value): if len(list(self.masterChannelList.keys())) == 1: # mdf resampled var[name] = f.createVariable(CleanedName, dataType, (list(self.masterChannelList.keys())[0], )) else: # not resampled - var[name] = f.createVariable(CleanedName, dataType, (self.getChannelMaster(name), )) + var[name] = f.createVariable(CleanedName, dataType, (self.get_channel_master(name),)) # Create attributes setAttribute(var[name], 'title', CleanedName) - setAttribute(var[name], 'units', self.getChannelUnit(name)) - setAttribute(var[name], 'Description', self.getChannelDesc(name)) + setAttribute(var[name], 'units', self.get_channel_unit(name)) + setAttribute(var[name], 'Description', self.get_channel_desc(name)) if name in set(self.masterChannelList.keys()): setAttribute(var[name], 'Type', 'Master Channel') setAttribute(var[name], 'datatype', 'master') @@ -1005,7 +997,7 @@ def setAttribute(obj, name, value): grp = {} for channel in list(self.keys()): channelData = self.getChannelData(channel) - masterName = self.getChannelMaster(channel) + masterName = self.get_channel_master(channel) if masterField in self[channel] and masterName not in list(groups.keys()): # create new data group ngroups += 1 @@ -1018,7 +1010,7 @@ def setAttribute(obj, name, value): grp[ngroups] = filegroup.create_group(group_name) setAttribute(grp[ngroups], masterField, masterName) setAttribute(grp[ngroups], masterTypeField, - masterTypeDict[self.getChannelMasterType(channel)]) + masterTypeDict[self.get_channel_master_type(channel)]) elif masterField in self[channel] and masterName in list(groups.keys()): group_name = masterName if channelData.dtype.kind not in ('U', 'O'): # not supported type @@ -1026,23 +1018,23 @@ def setAttribute(obj, name, value): data=channelData, compression=compression, compression_opts=compression_opts) - setAttribute(dset, unitField, self.getChannelUnit(channel)) + setAttribute(dset, unitField, self.get_channel_unit(channel)) if descriptionField in self[channel]: - setAttribute(dset, descriptionField, self.getChannelDesc(channel)) + setAttribute(dset, descriptionField, self.get_channel_desc(channel)) else: # resampled or only one time for all channels : no groups masterName = list(self.masterChannelList.keys())[0] setAttribute(filegroup, masterField, masterName) setAttribute(filegroup, masterTypeField, - masterTypeDict[self.getChannelMasterType(masterName)]) + masterTypeDict[self.get_channel_master_type(masterName)]) for channel in list(self.keys()): channelData = self.getChannelData(channel) if channelData.dtype.kind not in ('U', 'O'): # not supported type dset = filegroup.create_dataset(channel, data=channelData, compression=compression, compression_opts=compression_opts) - setAttribute(dset, unitField, self.getChannelUnit(channel)) + setAttribute(dset, unitField, self.get_channel_unit(channel)) if descriptionField in self[channel]: - setAttribute(dset, descriptionField, self.getChannelDesc(channel)) + setAttribute(dset, descriptionField, self.get_channel_desc(channel)) f.close() def exportToMatlab(self, filename=None): @@ -1114,9 +1106,9 @@ def exportToExcel(self, filename=None): wb = xlwt.Workbook(encoding=coding) channelList = list(self.keys()) if PythonVersion < 3: - Units = [self.getChannelUnit(channel).decode(coding, 'replace') for channel in list(self.keys())] + Units = [self.get_channel_unit(channel).decode(coding, 'replace') for channel in list(self.keys())] else: - Units = [self.getChannelUnit(channel) for channel in list(self.keys())] + Units = [self.get_channel_unit(channel) for channel in list(self.keys())] # Excel 2003 limits maxCols = 255 maxLines = 65535 @@ -1190,7 +1182,7 @@ def exportToXlsx(self, filename=None): data = self.getChannelData(channel) if data.ndim <= 1: # not an array channel ws.cell(row=1, column=ncol).value = channel - ws.cell(row=2, column=ncol).value = self.getChannelUnit(channel) + ws.cell(row=2, column=ncol).value = self.get_channel_unit(channel) try: if data.ndim <= 1: # not an array channel if data.dtype.kind in ('i', 'u') or 'f4' in data.dtype.str: @@ -1222,7 +1214,7 @@ def keepChannels(self, channelList): # avoid to remove master channels otherwise problems with resample removeChannels.append(channel) if not len(removeChannels) == 0: - [self.masterChannelList[self.getChannelMaster(channel)].remove(channel) for channel in removeChannels] + [self.masterChannelList[self.get_channel_master(channel)].remove(channel) for channel in removeChannels] [self.pop(channel) for channel in removeChannels] def mergeMdf(self, mdfClass): @@ -1248,22 +1240,22 @@ def mergeMdf(self, mdfClass): data = self.getChannelData(channel) mdfData = mdfClass.getChannelData(channel) if not channel == 'master': - self.setChannelData(channel, hstack((data, mdfData))) + self.set_channel_data(channel, hstack((data, mdfData))) else: offset = mean(diff(mdfData)) # sampling offset = data[-1] + offset # time offset - self.setChannelData(channel, hstack((data, mdfData + offset))) + self.set_channel_data(channel, hstack((data, mdfData + offset))) elif channel in mdfClass: # new channel for self from mdfClass mdfData = mdfClass.getChannelData(channel) self[channel] = mdfClass[channel] # initialise all fields, units, descriptions, etc. refill = empty(initialTimeSize) refill.fil(nan) # fill with NANs - self.setChannelData(channel, hstack((refill, mdfData))) # readjust against time + self.set_channel_data(channel, hstack((refill, mdfData))) # readjust against time else: # channel missing in mdfClass data = self.getChannelData(channel) refill = empty(len(mdfClass.getChannelData('master'))) refill.fill(nan) # fill with NANs - self.setChannelData(channel, hstack((data, refill))) + self.set_channel_data(channel, hstack((data, refill))) def copy(self): """make a shallow copy a mdf class @@ -1315,7 +1307,7 @@ def convertToPandas(self, sampling=None): for group in self.masterChannelList: if group not in self.masterChannelList[group]: warn('no master channel in group {}'.format(group)) - elif self.getChannelMasterType(group) != 1: + elif self.get_channel_master_type(group) != 1: warn('Warning: master channel is not time, ' 'not appropriate conversion for pandas') temp = {} @@ -1344,6 +1336,7 @@ def convertToPandas(self, sampling=None): self.masterChannelList = {} self._pandasframe = True + if __name__ == "__main__": try: from multiprocessing import freeze_support From 195faaa5eeabee1b0f8e326411300c60a18fdba7 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Wed, 24 Oct 2018 01:10:03 +0200 Subject: [PATCH 31/61] Some pep8 refactoring --- mdfreader/mdf4reader.py | 4 ++-- mdfreader/mdfinfo4.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index 3ce5a92..9a8b74b 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -758,8 +758,8 @@ def readSortedRecord(self, fid, info, channelSet=None): ---------------- fid : file identifier - pointer - position in file of data block beginning + info + info class channelSet : set of str, optional set of channel to read diff --git a/mdfreader/mdfinfo4.py b/mdfreader/mdfinfo4.py index 954c8e9..7975055 100644 --- a/mdfreader/mdfinfo4.py +++ b/mdfreader/mdfinfo4.py @@ -1255,7 +1255,7 @@ def write(self, fid, data): class Info4(dict): - __slots__ = ['file_name', 'fid', 'zipfile'] + __slots__ = ['fileName', 'fid', 'zipfile'] """ information block parser fo MDF file version 4.x Attributes From 4f7901735366f9b3b1fd23192a31952aebe99873 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Wed, 31 Oct 2018 21:34:59 +0100 Subject: [PATCH 32/61] Some pep8 refactoring --- mdfForVeuszPlugin.py | 20 +- mdfconverter/mdfreaderui4.py | 38 +- mdfconverter/mdfreaderui5.py | 38 +- mdfreader/__init__.py | 6 +- mdfreader/__main__.py | 2 +- mdfreader/channel.py | 773 ++++++++++++++++----------------- mdfreader/mdf.py | 28 +- mdfreader/mdf3reader.py | 671 ++++++++++++++-------------- mdfreader/mdf4reader.py | 688 +++++++++++++++-------------- mdfreader/mdfinfo3.py | 226 +++++----- mdfreader/mdfinfo4.py | 241 ++++++----- mdfreader/mdfreader.py | 817 ++++++++++++++++++----------------- 12 files changed, 1776 insertions(+), 1772 deletions(-) diff --git a/mdfForVeuszPlugin.py b/mdfForVeuszPlugin.py index cf8981f..c557bb9 100644 --- a/mdfForVeuszPlugin.py +++ b/mdfForVeuszPlugin.py @@ -17,8 +17,8 @@ from veusz.plugins.datasetplugin import Dataset1D as ImportDataset1D from veusz.plugins.field import FieldFloat as ImportFieldFloat try: - from mdfreader import mdf - from mdfreader import mdfinfo + from mdfreader import Mdf + from mdfreader import MdfInfo except ImportError: try: from veusz.plugins.mdfreader import mdf @@ -29,11 +29,11 @@ import os.path sys.path.append(os.getcwdu()) print(os.path.join(os.getcwdu(), 'plugins')) - from mdfreader import mdf - from mdfreader import mdfinfo + from mdfreader import Mdf + from mdfreader import MdfInfo -class ImportPlugin(mdfinfo): +class ImportPlugin(MdfInfo): """Define a plugin to read data in a particular format. @@ -58,7 +58,7 @@ def getPreview(self, params): Returns (text, okaytoimport) """ - info = mdfinfo(fileName=params.filename) + info = MdfInfo() if info.mdfversion < 400: f = '' @@ -85,7 +85,7 @@ def getPreview(self, params): f += 'Project Name: ' + Comment['project'] + '\n' if 'subject' in Comment: f += 'Subject: ' + Comment['subject'] + '\n' + 'Channel List:\n' - for channelName in info.listChannels(): + for channelName in info.list_channels(): f += ' ' + channelName + '\n' return f, True @@ -97,7 +97,7 @@ def doImport(self, params): return [] -class MdfImportPlugin(ImportPlugin, mdf): +class MdfImportPlugin(ImportPlugin, Mdf): """Plugin to import mdf (Mostly ETAS INCA or CANape files)""" @@ -115,8 +115,8 @@ def doImport(self, params): Return a list of ImportDataset1D, ImportDataset2D objects """ - data = mdf(params.filename) - data.resample(samplingTime=params.field_results['mult']) + data = Mdf(params.filename) + data.resample(sampling_time=params.field_results['mult']) List = [] for channelName in list(data.keys()): if len(data[channelName]['data']) > 0 and not data[channelName]['data'].dtype.kind in ['S', 'U']: diff --git a/mdfconverter/mdfreaderui4.py b/mdfconverter/mdfreaderui4.py index 4469dd0..d8ad158 100644 --- a/mdfconverter/mdfreaderui4.py +++ b/mdfconverter/mdfreaderui4.py @@ -35,8 +35,8 @@ def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.setupUi(self) self.fileNames = [] # files to convert - self.mdfClass = mdf() # instance of mdf - self.mdfinfoClass = mdfinfo() # instance of mdfinfo + self.mdfClass = Mdf() # instance of mdf + self.mdfinfoClass = MdfInfo() # instance of mdfinfo self.convertSelection = 'Matlab' # by default Matlab conversion is selected self.MergeFiles = False # by default self.labFileName = [] # .lab file name @@ -66,7 +66,7 @@ def on_browse_clicked(self): self.mdfinfoClass.__init__() self.cleanChannelList() self.cleanSelectedChannelList() - ChannelList = convertChannelList(self.mdfinfoClass.listChannels(str(self.fileNames[0]))) + ChannelList = convertChannelList(self.mdfinfoClass.list_channels(str(self.fileNames[0]))) self.SelectedChannelList.addItems(ChannelList) self.FileList.setItemSelected(self.FileList.item(0), True) @@ -145,20 +145,20 @@ def on_Convert_clicked(self): buffer.update(res[0]) # assigns next class to buffer buffer.masterChannelList = res[1] fileNameList.append(res[2]) - self.mdfClass.mergeMdf(buffer) # merge buffer to merged class mdfClass + self.mdfClass.merge_mdf(buffer) # merge buffer to merged class mdfClass # Export if self.convertSelection == 'Matlab': - self.mdfClass.exportToMatlab() + self.mdfClass.export_to_matlab() elif self.convertSelection == 'csv': - self.mdfClass.exportToCSV() + self.mdfClass.export_to_csv() elif self.convertSelection == 'netcdf': - self.mdfClass.exportToNetCDF() + self.mdfClass.export_to_NetCDF() elif self.convertSelection == 'hdf5': - self.mdfClass.exportToHDF5() + self.mdfClass.export_to_hdf5() elif self.convertSelection == 'excel': - self.mdfClass.exportToExcel() + self.mdfClass.export_to_excel() elif self.convertSelection == 'excel2010': - self.mdfClass.exportToXlsx() + self.mdfClass.export_to_xlsx() elif self.convertSelection == 'mdf3': self.mdfClass.write(fileName + '_new') self.cleanChannelList() @@ -176,7 +176,7 @@ def on_FileList_itemClicked(self, item): self.mdfinfoClass.__init__() # self.mdfinfoClass.readinfo(item) self.cleanChannelList() - ChannelList = convertChannelList(self.mdfinfoClass.listChannels(str(item.text()))) + ChannelList = convertChannelList(self.mdfinfoClass.list_channels(str(item.text()))) self.channelList.addItems(ChannelList) self.mdfinfoClass.__init__() # clean object to free memory @@ -301,26 +301,26 @@ def on_MergeFiles_toggled(self, checked): def processMDF(fileName, channelist, resampleFlag, resampleValue, convertFlag, convertSelection): # Will process file according to defined options - yop = mdf() + yop = Mdf() yop.multiProc = False # already multiprocessed yop.convertAfterRead = True yop.read(fileName) # reads complete file - yop.keepChannels(channelist) # removes unnecessary channels + yop.keep_channels(channelist) # removes unnecessary channels if resampleFlag: yop.resample(resampleValue) if convertFlag: if convertSelection == 'Matlab': - yop.exportToMatlab() + yop.export_to_matlab() elif convertSelection == 'csv': - yop.exportToCSV() + yop.export_to_csv() elif convertSelection == 'netcdf': - yop.exportToNetCDF() + yop.export_to_NetCDF() elif convertSelection == 'hdf5': - yop.exportToHDF5() + yop.export_to_hdf5() elif convertSelection == 'excel': - yop.exportToExcel() + yop.export_to_excel() elif convertSelection == 'excel2010': - yop.exportToXlsx() + yop.export_to_xlsx() elif convertSelection == 'mdf3': yop.write(fileName + '_new') yopPicklable = {} # picklable dict and not object diff --git a/mdfconverter/mdfreaderui5.py b/mdfconverter/mdfreaderui5.py index a617144..e0ef69b 100644 --- a/mdfconverter/mdfreaderui5.py +++ b/mdfconverter/mdfreaderui5.py @@ -34,8 +34,8 @@ def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.setupUi(self) self.fileNames = [] # files to convert - self.mdfClass = mdfreader.mdf() # instance of mdf - self.mdfinfoClass = mdfreader.mdfinfo() # instance of mdfinfo + self.mdfClass = mdfreader.Mdf() # instance of mdf + self.mdfinfoClass = mdfreader.MdfInfo() # instance of mdfinfo self.convertSelection = 'Matlab' # by default Matlab conversion is selected self.MergeFiles = False # by default self.labFileName = [] # .lab file name @@ -64,7 +64,7 @@ def on_browse_clicked(self): self.mdfinfoClass.__init__() self.cleanChannelList() self.cleanSelectedChannelList() - ChannelList = convertChannelList(self.mdfinfoClass.listChannels(str(self.fileNames[0]))) + ChannelList = convertChannelList(self.mdfinfoClass.list_channels(str(self.fileNames[0]))) self.SelectedChannelList.addItems(ChannelList) self.FileList.item(0).setSelected(True) @@ -142,20 +142,20 @@ def on_Convert_clicked(self): buffer.update(res[0]) # assigns next class to buffer buffer.masterChannelList = res[1] fileNameList.append(res[2]) - self.mdfClass.mergeMdf(buffer) # merge buffer to merged class mdfClass + self.mdfClass.merge_mdf(buffer) # merge buffer to merged class mdfClass # Export if self.convertSelection == 'Matlab': - self.mdfClass.exportToMatlab() + self.mdfClass.export_to_matlab() elif self.convertSelection == 'csv': - self.mdfClass.exportToCSV() + self.mdfClass.export_to_csv() elif self.convertSelection == 'netcdf': - self.mdfClass.exportToNetCDF() + self.mdfClass.export_to_NetCDF() elif self.convertSelection == 'hdf5': - self.mdfClass.exportToHDF5() + self.mdfClass.export_to_hdf5() elif self.convertSelection == 'excel': - self.mdfClass.exportToExcel() + self.mdfClass.export_to_excel() elif self.convertSelection == 'excel2010': - self.mdfClass.exportToXlsx() + self.mdfClass.export_to_xlsx() elif self.convertSelection == 'mdf3': self.mdfClass.write(fileName + '_new') self.cleanChannelList() @@ -172,7 +172,7 @@ def on_FileList_itemClicked(self, item): self.mdfinfoClass.__init__() # self.mdfinfoClass.readinfo(item) self.cleanChannelList() - ChannelList = convertChannelList(self.mdfinfoClass.listChannels(str(item.text()))) + ChannelList = convertChannelList(self.mdfinfoClass.list_channels(str(item.text()))) self.channelList.addItems(ChannelList) self.mdfinfoClass.__init__() # clean object to free memory @@ -288,26 +288,26 @@ def on_MergeFiles_toggled(self): def processMDF(fileName, channelist, resampleFlag, resampleValue, convertFlag, convertSelection): # Will process file according to defined options - yop = mdfreader.mdf() + yop = mdfreader.Mdf() yop.multiProc = False # already multiprocessed yop.convertAfterRead = True yop.read(fileName) # reads complete file - yop.keepChannels(channelist) # removes unnecessary channels + yop.keep_channels(channelist) # removes unnecessary channels if resampleFlag: yop.resample(resampleValue) if convertFlag: if convertSelection == 'Matlab': - yop.exportToMatlab() + yop.export_to_matlab() elif convertSelection == 'csv': - yop.exportToCSV() + yop.export_to_csv() elif convertSelection == 'netcdf': - yop.exportToNetCDF() + yop.export_to_NetCDF() elif convertSelection == 'hdf5': - yop.exportToHDF5() + yop.export_to_hdf5() elif convertSelection == 'excel': - yop.exportToExcel() + yop.export_to_excel() elif convertSelection == 'excel2010': - yop.exportToXlsx() + yop.export_to_xlsx() elif convertSelection == 'mdf3': yop.write(fileName + '_new') yopPicklable = {} # picklable dict and not object diff --git a/mdfreader/__init__.py b/mdfreader/__init__.py index ddd2be0..285619a 100644 --- a/mdfreader/__init__.py +++ b/mdfreader/__init__.py @@ -18,9 +18,9 @@ __license__ = 'GPLV3' __version__ = "2.8" -from .mdfreader import mdf, mdfinfo +from .mdfreader import Mdf, MdfInfo __all__ = [ - 'mdf', - 'mdfinfo' + 'Mdf', + 'MdfInfo' ] diff --git a/mdfreader/__main__.py b/mdfreader/__main__.py index 8bc2b13..6f1f0c3 100644 --- a/mdfreader/__main__.py +++ b/mdfreader/__main__.py @@ -3,4 +3,4 @@ import sys import mdfreader warn(sys.argv[1:][0]) -mdfreader.mdf(sys.argv[1:][0]) +mdfreader.Mdf(sys.argv[1:][0]) diff --git a/mdfreader/channel.py b/mdfreader/channel.py index a95e2b3..d6784b7 100644 --- a/mdfreader/channel.py +++ b/mdfreader/channel.py @@ -26,7 +26,7 @@ class Channel4(object): __slots__ = ['channelNumber', 'channelGroup', 'dataGroup', - 'type', 'name', 'VLSD_CG_Flag', 'nBytes', 'byteOffset'] + 'type', 'name', 'VLSD_CG_Flag', 'nBytes', 'byteOffset', 'bit_masking_needed'] """ channel class gathers all about channel structure in a record Attributes @@ -46,6 +46,10 @@ class Channel4(object): flag when Channel Group VLSD is used nBytes : int number of bytes taken by channel at each sampling + byteOffset : int + byte offset in record + bit_masking_needed : boolean + Methods ------------ @@ -55,14 +59,14 @@ class Channel4(object): to print class attributes attachment(fid, info) in case of sync channel attached - set(info, dataGroup, channelGroup, channelNumber, recordIDsize) + set(info, data_group, channel_group, channel_number, record_id_size) standard channel initialisation - setCANOpen(info, dataGroup, channelGroup, channelNumber, - recordIDsize, name) + set_CANOpen(info, data_group, channel_group, channel_number, + record_id_size, name) CANOpen channel initialisation - setInvalidBytes(info, dataGroup, channelGroup, recordIDsize, byte_aligned) + set_invalid_bytes(info, data_group, channel_group, record_id_size, byte_aligned) Invalid Bytes channel initialisation - recAttributeName : str + rec_attribute_name : str Name of channel compatible with python attribute name conventions unit : str, default empty string channel unit @@ -70,49 +74,47 @@ class Channel4(object): channel description conversion : info class conversion dictionnary - CNBlock : info class + cn_block : info class Channel Block info class - signalDataType : int + signal_data_type : int signal type according to specification - bitCount : int + bit_count : int number of bits used to store channel record calc_bytes : int number of bytes (1 byte = 8 bits) taken by channel record little_endian : Bool flag to inform of channel data endian - dataFormat : str + data_format : str numpy dtype as string - Format : + c_format : C format understood by fread - CFormat : struct class instance + c_format_structure : struct class instance struct instance to convert from C Format - byteOffset : int + byte_offset : int position of channel record in complete record in bytes - bitOffset : int + bit_offset : int bit position of channel value inside byte in case of channel having bit count below 8 - RecordFormat : nested tuple of str + record_format : nested tuple of str dtype format used for numpy.core.records functions ((name_title,name),str_stype) - nativeRecordFormat : nested tuple of str + native_record_format : nested tuple of str same as RecordFormat but using recAttributeName instead of name - channelType : int + channel_type : int channel type ; 0 fixed length data, 1 VLSD, 2 master, 3 virtual master, 4 sync, 5 MLSD, 6 virtual data - channelSyncType : int + channel_sync_type : int channel synchronisation type ; 0 None, 1 Time, 2 Angle, 3 Distance, 4 Index - posByteBeg : int + pos_byte_beg : int start position in number of byte of channel record in complete record - posByteEnd : int + pos_byte_end : int end position in number of byte of channel record in complete record - posBitBeg : int + pos_bit_beg : int start position in number of bit of channel record in complete record - posBitEnd : int + pos_bit_end : int end position in number of bit of channel record in complete record - maxLengthVLSDRecord : - - CABlock : CABlock class + ca_block : CABlock class contains CABLock data : int pointer to data block linked to a channel (VLSD, MLSD) @@ -193,7 +195,7 @@ def data(self, info): except KeyError: return None - def CNBlock(self, info): + def cn_block(self, info): """ channel block Parameters @@ -211,7 +213,7 @@ def CNBlock(self, info): except KeyError: return None - def signalDataType(self, info, byte_aligned=True): + def signal_data_type(self, info, byte_aligned=True): """ extract signal data type from info4 class Parameters @@ -249,7 +251,7 @@ def signalDataType(self, info, byte_aligned=True): else: return 0 # uint LE - def bitCount(self, info): + def bit_count(self, info): """ calculates channel number of bits Parameters @@ -266,7 +268,7 @@ def bitCount(self, info): return info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_bit_count'] elif self.type == 3: # CAN channel if self.name == 'ms': - if self.signalDataType(info) == 13: + if self.signal_data_type(info) == 13: return 16 else: return 32 @@ -279,7 +281,7 @@ def bitCount(self, info): else: warn('Not found channel type') - def channelSyncType(self, info): + def channel_sync_type(self, info): """ Extracts channel sync type from info4 Parameters @@ -303,7 +305,7 @@ def channelSyncType(self, info): except KeyError: return 0 # in case of invalid bytes channel - def CABlock(self, info): + def ca_block(self, info): """ Extracts channel CA Block from info4 Parameters @@ -321,14 +323,14 @@ def CABlock(self, info): except KeyError: return None - def isCABlock(self, info): + def is_ca_block(self, info): try: info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['CABlock'] return True except KeyError: return False - def recordIDsize(self, info): + def record_id_size(self, info): """ Extracts record id size from info4 Parameters @@ -348,7 +350,7 @@ def recordIDsize(self, info): """ return info['DG'][self.dataGroup]['dg_rec_id_size'] - def channelType(self, info): + def channel_type(self, info): """ Extracts channel type from info4 Parameters @@ -405,26 +407,26 @@ def calc_bytes(self, info): number of bytes integer """ if not self.type == 4: # not channel containing invalid bit - nBytes = _bits_to_bytes(info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_bit_count'] + n_bytes = _bits_to_bytes(info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_bit_count'] + info['CN'][self.dataGroup][self.channelGroup][self.channelNumber] ['cn_bit_offset'], self.isnumeric(info)) if self.type in (1, 2): # array channel - nBytes *= self.CABlock(info)['PNd'] - Block = self.CABlock(info) - while 'CABlock' in Block: # nested array - Block = Block['CABlock'] - nBytes *= Block['PNd'] + n_bytes *= self.ca_block(info)['PNd'] + block = self.ca_block(info) + while 'CABlock' in block: # nested array + block = block['CABlock'] + n_bytes *= block['PNd'] if self.type == 3: # CAN channel if self.name == 'ms': if info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_data_type'] == 13: - nBytes = 2 + n_bytes = 2 else: - nBytes = 4 + n_bytes = 4 elif self.name == 'days': - nBytes = 2 + n_bytes = 2 else: - nBytes = 1 - return nBytes + n_bytes = 1 + return n_bytes else: return info['CG'][self.dataGroup][self.channelGroup]['cg_invalid_bytes'] @@ -447,7 +449,7 @@ def little_endian(self, info): else: return True - def recAttributeName(self): + def record_attribute_name(self): """ clean up channel name from unauthorised characters Returns @@ -471,16 +473,16 @@ def numpy_format(self, info): """ endian = '' if self.type == 4: # Invalid bit channel - dataformat = '{}V'.format(self.nBytes) + data_format = '{}V'.format(self.nBytes) elif info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_composition'] and \ 'CABlock' in info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]: # channel array - CABlock = info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['CABlock'] - endian, dataformat = arrayformat4( + ca_block = info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['CABlock'] + endian, data_format = array_format4( info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_data_type'], info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_bit_count'] // 8) # calculates total array size in bytes - array_desc = CABlock['ca_dim_size'] - Block = CABlock + array_desc = ca_block['ca_dim_size'] + Block = ca_block while 'CABlock' in Block: # nested array Block = Block['CABlock'] if isinstance(array_desc, list): @@ -491,25 +493,24 @@ def numpy_format(self, info): array_desc = str(tuple(array_desc)) else: array_desc = str(array_desc) - dataformat = array_desc + dataformat + data_format = array_desc + data_format elif self.type == 3: # CAN channel if self.name == 'ms': - if self.signalDataType(info) == 13: - dataformat = 'u2' + if self.signal_data_type(info) == 13: + data_format = 'u2' else: - dataformat = 'u4' + data_format = 'u4' elif self.name == 'days': - dataformat = 'u2' + data_format = 'u2' else: - dataformat = 'u1' + data_format = 'u1' endian = '<' else: # not channel array - endian, dataformat = arrayformat4( - info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_data_type'], - self.nBytes) - return endian, dataformat + endian, data_format = array_format4( + info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_data_type'], self.nBytes) + return endian, data_format - def dataFormat(self, info): + def data_format(self, info): """ channel numpy.core.records data format Parameters @@ -522,14 +523,14 @@ def dataFormat(self, info): ----------- string data format """ - endian, dataformat = self.numpy_format(info) - return ''.join([endian, dataformat]) + endian, _data_format = self.numpy_format(info) + return ''.join([endian, _data_format]) - def nativedataFormat(self, info): - endian, nativedataFormat = self.numpy_format(info) - return nativedataFormat + def native_data_format(self, info): + endian, _native_data_format = self.numpy_format(info) + return _native_data_format - def Format(self, info): + def c_format(self, info): """ channel data C format Parameters @@ -542,24 +543,24 @@ def Format(self, info): ----------- string data C format """ - signalDataType = self.signalDataType(info) + signal_data_type = self.signal_data_type(info) if self.type == 0: # standard channel - if signalDataType not in (13, 14): - if not self.channelType(info) == 1: # if not VSLD - endian, dataType = datatypeformat4(signalDataType, self.nBytes) + if signal_data_type not in (13, 14): + if not self.channel_type(info) == 1: # if not VSLD + endian, data_type = data_type_format4(signal_data_type, self.nBytes) else: # VLSD - endian, dataType = datatypeformat4(0, self.nBytes) - return '{}{}'.format(endian, dataType) + endian, data_type = data_type_format4(0, self.nBytes) + return '{}{}'.format(endian, data_type) elif self.type in (1, 2): # array channel - CA = self.CABlock(info) - nBytes = _bits_to_bytes(info['CN'][self.dataGroup][self.channelGroup] + ca = self.ca_block(info) + n_bytes = _bits_to_bytes(info['CN'][self.dataGroup][self.channelGroup] [self.channelNumber]['cn_bit_count'] + info['CN'][self.dataGroup][self.channelGroup] [self.channelNumber]['cn_bit_offset'], self.isnumeric(info)) - endian, dataType = datatypeformat4(signalDataType, nBytes) - return '{}{}{}'.format(endian, CA['PNd'], dataType) + endian, data_type = data_type_format4(signal_data_type, n_bytes) + return '{}{}{}'.format(endian, ca['PNd'], data_type) elif self.type == 3: # CAN channel if self.name == 'ms': - if signalDataType == 13: + if signal_data_type == 13: return 'H' else: return 'I' @@ -572,7 +573,7 @@ def Format(self, info): else: warn('Not found channel type') - def CFormat(self, info): + def c_format_structure(self, info): """ channel data C format struct object Parameters @@ -585,9 +586,9 @@ def CFormat(self, info): ----------- string data C format struct object """ - return Struct(self.Format(info)) + return Struct(self.c_format(info)) - def CANOpenOffset(self): + def CANOpen_offset(self): """ CANopen channel bytes offset Returns @@ -600,7 +601,7 @@ def CANOpenOffset(self): warn('CANopen type not understood') return None - def bitOffset(self, info): + def bit_offset(self, info): """ channel data bit offset in record Parameters @@ -617,13 +618,13 @@ def bitOffset(self, info): return info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_bit_offset'] elif self.type == 3: # CAN channel return info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_bit_offset'] \ - + self.CANOpenOffset() * 8 + + self.CANOpen_offset() * 8 elif self.type == 4: # Invalid bit channel return 0 else: warn('Not found channel type') - def calc_byteOffset(self, info): + def calc_byte_offset(self, info): """ channel data bytes offset in record (without record id) Parameters @@ -640,13 +641,13 @@ def calc_byteOffset(self, info): return info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_byte_offset'] elif self.type == 3: # CAN channel return info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_byte_offset'] \ - + self.CANOpenOffset() + + self.CANOpen_offset() elif self.type == 4: # Invalid bit channel return info['CG'][self.dataGroup][self.channelGroup]['cg_data_bytes'] else: warn('Not found channel type') - def posByteBeg(self, info): + def pos_byte_beg(self, info): """ channel data bytes starting position in record Parameters @@ -659,9 +660,9 @@ def posByteBeg(self, info): ----------- integer, channel bytes starting position """ - return self.recordIDsize(info) + self.byteOffset + return self.record_id_size(info) + self.byteOffset - def posByteEnd(self, info): + def pos_byte_end(self, info): """ channel data bytes ending position in record Parameters @@ -674,9 +675,9 @@ def posByteEnd(self, info): ----------- integer, channel bytes ending position """ - return self.posByteBeg(info) + self.nBytes + return self.pos_byte_beg(info) + self.nBytes - def posBitBeg(self, info): + def pos_bit_beg(self, info): """ channel data bit starting position in record Parameters @@ -689,9 +690,9 @@ def posBitBeg(self, info): ----------- integer, channel bit starting position """ - return self.posByteBeg(info) * 8 + self.bitOffset(info) + return self.pos_byte_beg(info) * 8 + self.bit_offset(info) - def posBitEnd(self, info): + def pos_bit_end(self, info): """ channel data bit ending position in record Parameters @@ -704,7 +705,7 @@ def posBitEnd(self, info): ----------- integer, channel bit ending position """ - return self.posBitBeg(info) + self.bitCount(info) + return self.pos_bit_beg(info) + self.bit_count(info) def unit(self, info): """ channel unit @@ -747,8 +748,7 @@ def desc(self, info): if not self.type == 3: # CAN channel if self.channelNumber in info['CN'][self.dataGroup][self.channelGroup]: if 'Comment' in info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]: - desc = info['CN'][self.dataGroup][self.channelGroup]\ - [self.channelNumber]['Comment'] + desc = info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['Comment'] if (desc is not None) and isinstance(desc, dict): if 'description' in desc: desc = desc['description'] @@ -758,8 +758,8 @@ def desc(self, info): desc = '' return desc else: - return 'Invalid Bytes DGgroup {0} CGgroup {1}'.format(self.dataGroup, - self.channelGroup) + return 'Invalid Bytes DG group {0} CG group {1}'.format(self.dataGroup, + self.channelGroup) else: return self.name @@ -781,47 +781,47 @@ def conversion(self, info): except KeyError: return None - def set(self, info, dataGroup, channelGroup, channelNumber): + def set(self, info, data_group, channel_group, channel_number): """ channel initialisation Parameters ------------ info : mdfinfo4.info4 class - dataGroup : int + data_group : int data group number in mdfinfo4.info4 class - channelGroup : int + channel_group : int channel group number in mdfinfo4.info4 class - channelNumber : int + channel_number : int channel number in mdfinfo4.info4 class """ - self.name = info['CN'][dataGroup][channelGroup][channelNumber]['name'] - self.channelNumber = channelNumber - self.dataGroup = dataGroup - self.channelGroup = channelGroup + self.name = info['CN'][data_group][channel_group][channel_number]['name'] + self.channelNumber = channel_number + self.dataGroup = data_group + self.channelGroup = channel_group self.type = 0 - if info['CN'][dataGroup][channelGroup][channelNumber]['cn_composition'] and \ - 'CABlock' in info['CN'][dataGroup][channelGroup][channelNumber]: + if info['CN'][data_group][channel_group][channel_number]['cn_composition'] and \ + 'CABlock' in info['CN'][data_group][channel_group][channel_number]: # channel array self.type = 1 - Block = info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['CABlock'] - if 'CABlock' in Block: # nested array + block = info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['CABlock'] + if 'CABlock' in block: # nested array self.type = 2 self.nBytes = self.calc_bytes(info) - self.byteOffset = self.calc_byteOffset(info) + self.byteOffset = self.calc_byte_offset(info) - def setCANOpen(self, info, dataGroup, channelGroup, channelNumber, name): + def set_CANOpen(self, info, data_group, channel_group, channel_number, name): """ CANOpen channel intialisation Parameters ------------ info : mdfinfo4.info4 class - dataGroup : int + data_group : int data group number in mdfinfo4.info4 class - channelGroup : int + channel_group : int channel group number in mdfinfo4.info4 class - channelNumber : int + channel_number : int channel number in mdfinfo4.info4 class name : str name of channel. Should be in ('ms', 'day', 'days', 'hour', @@ -829,33 +829,33 @@ def setCANOpen(self, info, dataGroup, channelGroup, channelNumber, name): """ self.type = 3 self.name = name - self.channelNumber = channelNumber - self.dataGroup = dataGroup - self.channelGroup = channelGroup + self.channelNumber = channel_number + self.dataGroup = data_group + self.channelGroup = channel_group self.nBytes = self.calc_bytes(info) - self.byteOffset = self.calc_byteOffset(info) + self.byteOffset = self.calc_byte_offset(info) - def setInvalidBytes(self, info, dataGroup, channelGroup, channelNumber): + def set_invalid_bytes(self, info, data_group, channel_group, channel_number): """ invalid_bytes channel initialisation Parameters ---------- info : mdfinfo4.info4 class - dataGroup : int + data_group : int data group number in mdfinfo4.info4 class - channelGroup : int + channel_group : int channel group number in mdfinfo4.info4 class - channelNumber : int + channel_number : int channel number in mdfinfo4.info4 class """ self.type = 4 - self.name = 'invalid_bytes{}'.format(dataGroup) - self.channelNumber = channelNumber - self.dataGroup = dataGroup - self.channelGroup = channelGroup + self.name = 'invalid_bytes{}'.format(data_group) + self.channelNumber = channel_number + self.dataGroup = data_group + self.channelGroup = channel_group self.nBytes = self.calc_bytes(info) - self.byteOffset = self.calc_byteOffset(info) + self.byteOffset = self.calc_byte_offset(info) def invalid_bit(self, info): """ extracts from info4 the channels valid bits positions @@ -879,16 +879,16 @@ def has_invalid_bit(self, info): else: return False - def changeChannelName(self, channelGroup): + def change_channel_name(self, channel_group): """ In case of duplicate channel names within several channel groups for unsorted data, rename channel name Parameters ------------ - channelGroup : int - channelGroup bumber + channel_group : int + channelGroup number """ - self.name = '{0}_{1}'.format(self.name, channelGroup) + self.name = '{0}_{1}'.format(self.name, channel_group) def bit_masking_needed(self, info): """ Valid if bit masking need @@ -904,227 +904,227 @@ def bit_masking_needed(self, info): boolean True if channel needs bit masking, otherwise False """ - if not self.nBytes == self.bitCount(info) / 8: + if not self.nBytes == self.bit_count(info) / 8: self.bit_masking_needed = True else: self.bit_masking_needed = False -def arrayformat4(signalDataType, numberOfBytes): +def array_format4(signal_data_type, number_of_bytes): """ function returning numpy style string from channel data type and number of bits Parameters ---------------- - signalDataType : int + signal_data_type : int channel data type according to specification - numberOfBytes : int + number_of_bytes : int number of bytes taken by channel data in a record Returns ----------- - endian, dataType : str + endian, data_type : str numpy dtype format used by numpy.core.records to read channel raw data """ - if signalDataType == 0: # unsigned, low endian - if numberOfBytes == 1: - dataType = 'u1' - elif numberOfBytes == 2: - dataType = 'u2' - elif numberOfBytes <= 4: - dataType = 'u4' - elif numberOfBytes <= 8: - dataType = 'u8' + if signal_data_type == 0: # unsigned, low endian + if number_of_bytes == 1: + data_type = 'u1' + elif number_of_bytes == 2: + data_type = 'u2' + elif number_of_bytes <= 4: + data_type = 'u4' + elif number_of_bytes <= 8: + data_type = 'u8' else: - dataType = '{}V'.format(numberOfBytes) + data_type = '{}V'.format(number_of_bytes) endian = '<' - elif signalDataType == 2: # signed int, low endian - if numberOfBytes == 1: - dataType = 'i1' - elif numberOfBytes == 2: - dataType = 'i2' - elif numberOfBytes <= 4: - dataType = 'i4' - elif numberOfBytes <= 8: - dataType = 'i8' + elif signal_data_type == 2: # signed int, low endian + if number_of_bytes == 1: + data_type = 'i1' + elif number_of_bytes == 2: + data_type = 'i2' + elif number_of_bytes <= 4: + data_type = 'i4' + elif number_of_bytes <= 8: + data_type = 'i8' else: - warn('Unsupported number of bytes for signed int {}'.format(numberOfBytes)) + warn('Unsupported number of bytes for signed int {}'.format(number_of_bytes)) endian = '<' - elif signalDataType == 4: # floating point, low endian - if numberOfBytes == 4: - dataType = 'f4' - elif numberOfBytes == 8: - dataType = 'f8' + elif signal_data_type == 4: # floating point, low endian + if number_of_bytes == 4: + data_type = 'f4' + elif number_of_bytes == 8: + data_type = 'f8' else: - warn('Unsupported number of bytes for floating point {}'.format(numberOfBytes)) + warn('Unsupported number of bytes for floating point {}'.format(number_of_bytes)) endian = '<' - elif signalDataType == 1: # unsigned, big endian - if numberOfBytes == 1: - dataType = 'u1' - elif numberOfBytes == 2: - dataType = 'u2' - elif numberOfBytes <= 4: - dataType = 'u4' - elif numberOfBytes <= 8: - dataType = 'u8' + elif signal_data_type == 1: # unsigned, big endian + if number_of_bytes == 1: + data_type = 'u1' + elif number_of_bytes == 2: + data_type = 'u2' + elif number_of_bytes <= 4: + data_type = 'u4' + elif number_of_bytes <= 8: + data_type = 'u8' else: - dataType = '{}V'.format(numberOfBytes) + data_type = '{}V'.format(number_of_bytes) endian = '>' - elif signalDataType == 3: # signed int, big endian - if numberOfBytes == 1: - dataType = 'i1' - elif numberOfBytes == 2: - dataType = 'i2' - elif numberOfBytes <= 4: - dataType = 'i4' - elif numberOfBytes <= 8: - dataType = 'i8' + elif signal_data_type == 3: # signed int, big endian + if number_of_bytes == 1: + data_type = 'i1' + elif number_of_bytes == 2: + data_type = 'i2' + elif number_of_bytes <= 4: + data_type = 'i4' + elif number_of_bytes <= 8: + data_type = 'i8' else: - warn('Unsupported number of bytes for signed int {}'.format(numberOfBytes)) + warn('Unsupported number of bytes for signed int {}'.format(number_of_bytes)) endian = '>' - elif signalDataType == 5: # floating point, big endian - if numberOfBytes == 4: - dataType = 'f4' - elif numberOfBytes == 8: - dataType = 'f8' + elif signal_data_type == 5: # floating point, big endian + if number_of_bytes == 4: + data_type = 'f4' + elif number_of_bytes == 8: + data_type = 'f8' else: - warn('Unsupported number of bytes for floating point {}'.format(numberOfBytes)) + warn('Unsupported number of bytes for floating point {}'.format(number_of_bytes)) endian = '>' - elif signalDataType == 6: # string ISO-8859-1 Latin - dataType = 'S{}'.format(numberOfBytes) + elif signal_data_type == 6: # string ISO-8859-1 Latin + data_type = 'S{}'.format(number_of_bytes) endian = '' - elif signalDataType == 7: # UTF-8 - dataType = 'S{}'.format(numberOfBytes) + elif signal_data_type == 7: # UTF-8 + data_type = 'S{}'.format(number_of_bytes) endian = '' - elif signalDataType == 8: # UTF-16 low endian - dataType = 'S{}'.format(numberOfBytes) + elif signal_data_type == 8: # UTF-16 low endian + data_type = 'S{}'.format(number_of_bytes) endian = '<' - elif signalDataType == 9: # UTF-16 big endian - dataType = 'S{}'.format(numberOfBytes) + elif signal_data_type == 9: # UTF-16 big endian + data_type = 'S{}'.format(number_of_bytes) endian = '>' - elif signalDataType == 10: # bytes array - dataType = 'V{}'.format(numberOfBytes) + elif signal_data_type == 10: # bytes array + data_type = 'V{}'.format(number_of_bytes) endian = '' - elif signalDataType in (11, 12): # MIME sample or MIME stream - dataType = 'V{}'.format(numberOfBytes) + elif signal_data_type in (11, 12): # MIME sample or MIME stream + data_type = 'V{}'.format(number_of_bytes) endian = '' - elif signalDataType in (13, 14): # CANOpen date or time - dataType = '' + elif signal_data_type in (13, 14): # CANOpen date or time + data_type = '' endian = '' else: - warn('Unsupported Signal Data Type {} {}'.format(signalDataType, numberOfBytes)) + warn('Unsupported Signal Data Type {} {}'.format(signal_data_type, number_of_bytes)) - return endian, dataType + return endian, data_type -def datatypeformat4(signalDataType, numberOfBytes): +def data_type_format4(signal_data_type, number_of_bytes): """ function returning C format string from channel data type and number of bits Parameters ---------------- - signalDataType : int + signal_data_type : int channel data type according to specification - numberOfBytes : int + number_of_bytes : int number of bytes taken by channel data in a record Returns ----------- - dataType : str + data_type : str C format used by fread to read channel raw data """ - if signalDataType == 0: # unsigned int - if numberOfBytes == 1: - dataType = 'B' - elif numberOfBytes == 2: - dataType = 'H' - elif numberOfBytes <= 4: - dataType = 'I' - elif numberOfBytes <= 8: - dataType = 'Q' + if signal_data_type == 0: # unsigned int + if number_of_bytes == 1: + data_type = 'B' + elif number_of_bytes == 2: + data_type = 'H' + elif number_of_bytes <= 4: + data_type = 'I' + elif number_of_bytes <= 8: + data_type = 'Q' else: - dataType = '{}s'.format(numberOfBytes) + data_type = '{}s'.format(number_of_bytes) endian = '<' - elif signalDataType == 1: # unsigned int - if numberOfBytes == 1: - dataType = 'B' - elif numberOfBytes == 2: - dataType = 'H' - elif numberOfBytes <= 4: - dataType = 'I' - elif numberOfBytes <= 8: - dataType = 'Q' + elif signal_data_type == 1: # unsigned int + if number_of_bytes == 1: + data_type = 'B' + elif number_of_bytes == 2: + data_type = 'H' + elif number_of_bytes <= 4: + data_type = 'I' + elif number_of_bytes <= 8: + data_type = 'Q' else: - dataType = '{}s'.format(numberOfBytes) + data_type = '{}s'.format(number_of_bytes) endian = '>' - elif signalDataType == 2: # signed int - if numberOfBytes == 1: - dataType = 'b' - elif numberOfBytes == 2: - dataType = 'h' - elif numberOfBytes <= 4: - dataType = 'i' - elif numberOfBytes <= 8: - dataType = 'q' + elif signal_data_type == 2: # signed int + if number_of_bytes == 1: + data_type = 'b' + elif number_of_bytes == 2: + data_type = 'h' + elif number_of_bytes <= 4: + data_type = 'i' + elif number_of_bytes <= 8: + data_type = 'q' else: - warn('Unsupported number of bytes for signed int {}'.format(signalDataType)) + warn('Unsupported number of bytes for signed int {}'.format(signal_data_type)) endian = '<' - elif signalDataType == 3: # signed int - if numberOfBytes == 1: - dataType = 'b' - elif numberOfBytes == 2: - dataType = 'h' - elif numberOfBytes <= 4: - dataType = 'i' - elif numberOfBytes <= 8: - dataType = 'q' + elif signal_data_type == 3: # signed int + if number_of_bytes == 1: + data_type = 'b' + elif number_of_bytes == 2: + data_type = 'h' + elif number_of_bytes <= 4: + data_type = 'i' + elif number_of_bytes <= 8: + data_type = 'q' else: - warn('Unsupported number of bytes for signed int {}'.format(signalDataType)) + warn('Unsupported number of bytes for signed int {}'.format(signal_data_type)) endian = '>' - elif signalDataType == 4: # floating point - if numberOfBytes == 4: - dataType = 'f' - elif numberOfBytes == 8: - dataType = 'd' + elif signal_data_type == 4: # floating point + if number_of_bytes == 4: + data_type = 'f' + elif number_of_bytes == 8: + data_type = 'd' else: - warn('Unsupported number of bytes for floating point {}'.format(signalDataType)) + warn('Unsupported number of bytes for floating point {}'.format(signal_data_type)) endian = '<' - elif signalDataType == 5: # floating point - if numberOfBytes == 4: - dataType = 'f' - elif numberOfBytes == 8: - dataType = 'd' + elif signal_data_type == 5: # floating point + if number_of_bytes == 4: + data_type = 'f' + elif number_of_bytes == 8: + data_type = 'd' else: - warn('Unsupported number of bytes for floating point {}'.format(signalDataType)) + warn('Unsupported number of bytes for floating point {}'.format(signal_data_type)) endian = '>' - elif signalDataType in (6, 7, 10, 11, 12): # string/bytes - dataType = '{}s'.format(numberOfBytes) + elif signal_data_type in (6, 7, 10, 11, 12): # string/bytes + data_type = '{}s'.format(number_of_bytes) endian = '' - elif signalDataType == 8: # UTF16 string/bytes - dataType = '{}s'.format(numberOfBytes) + elif signal_data_type == 8: # UTF16 string/bytes + data_type = '{}s'.format(number_of_bytes) endian = '<' - elif signalDataType == 9: # UTF16 string/bytes - dataType = '{}s'.format(numberOfBytes) + elif signal_data_type == 9: # UTF16 string/bytes + data_type = '{}s'.format(number_of_bytes) endian = '>' else: - warn('Unsupported Signal Data Type {} {}'.format(signalDataType, numberOfBytes)) + warn('Unsupported Signal Data Type {} {}'.format(signal_data_type, number_of_bytes)) - return endian, dataType + return endian, data_type class Channel3: @@ -1179,58 +1179,59 @@ class Channel3: constructor __str__() to print class attributes + change_channel_name(channel_group) + rename duplicated channel name within unsorted channel groups """ - def __init__(self, info, dataGroup, channelGroup, - channelNumber, recordIDnumber): + def __init__(self, info, data_group, channel_group, channel_number, record_id_number): """ Channel class constructor Parameters ------------ info : mdfinfo3.info3 class - dataGroup : int + data_group : int data group number in mdfinfo3.info3 class - channelGroup : int + channel_group : int channel group number in mdfinfo3.info3 class - channelNumber : int + channel_number : int channel number in mdfinfo3.info3 class - recordIDnumber : int - Number of record IDs, each one Byte + record_id_number : int + Number of record ID, each one Byte """ - self.name = info['CNBlock'][dataGroup][channelGroup][channelNumber]['signalName'] - self.channelNumber = channelNumber - self.signalDataType = info['CNBlock'][dataGroup][channelGroup][channelNumber]['signalDataType'] - if not self.signalDataType in (7, 8): + self.name = info['CNBlock'][data_group][channel_group][channel_number]['signalName'] + self.channelNumber = channel_number + self.signalDataType = info['CNBlock'][data_group][channel_group][channel_number]['signalDataType'] + if self.signalDataType not in (7, 8): numeric = True else: numeric = False - self.bitCount = info['CNBlock'][dataGroup][channelGroup][channelNumber]['numberOfBits'] - ByteOrder = info['IDBlock']['ByteOrder'] - self.posBitBeg = info['CNBlock'][dataGroup][channelGroup][channelNumber]['numberOfTheFirstBits'] + self.bitCount = info['CNBlock'][data_group][channel_group][channel_number]['numberOfBits'] + byte_order = info['IDBlock']['ByteOrder'] + self.posBitBeg = info['CNBlock'][data_group][channel_group][channel_number]['numberOfTheFirstBits'] self.posBitEnd = self.posBitBeg + self.bitCount self.byteOffset = self.posBitBeg // 8 self.bitOffset = self.posBitBeg % 8 self.nBytes = _bits_to_bytes(self.bitCount + self.bitOffset, numeric) (self.dataFormat, self.nativedataFormat) = \ - _arrayformat3(self.signalDataType, self.nBytes, ByteOrder) - self.CFormat = Struct(_datatypeformat3(self.signalDataType, self.nBytes, ByteOrder)) + _array_format3(self.signalDataType, self.nBytes, byte_order) + self.CFormat = Struct(_data_type_format3(self.signalDataType, self.nBytes, byte_order)) self.embedding_channel_bitOffset = self.bitOffset # for channel containing other channels - self.posByteBeg = recordIDnumber + self.byteOffset - self.posByteEnd = recordIDnumber + self.byteOffset + self.nBytes + self.posByteBeg = record_id_number + self.byteOffset + self.posByteEnd = record_id_number + self.byteOffset + self.nBytes if not self.nBytes == self.bitCount / 8: self.bit_masking_needed = True else: self.bit_masking_needed = False - self.channelType = info['CNBlock'][dataGroup][channelGroup][channelNumber]['channelType'] - if 'physicalUnit' in info['CCBlock'][dataGroup][channelGroup][channelNumber]: - self.unit = info['CCBlock'][dataGroup][channelGroup][channelNumber]['physicalUnit'] + self.channelType = info['CNBlock'][data_group][channel_group][channel_number]['channelType'] + if 'physicalUnit' in info['CCBlock'][data_group][channel_group][channel_number]: + self.unit = info['CCBlock'][data_group][channel_group][channel_number]['physicalUnit'] else: self.unit = '' - if 'signalDescription' in info['CNBlock'][dataGroup][channelGroup][channelNumber]: - self.desc = info['CNBlock'][dataGroup][channelGroup][channelNumber]['signalDescription'] + if 'signalDescription' in info['CNBlock'][data_group][channel_group][channel_number]: + self.desc = info['CNBlock'][data_group][channel_group][channel_number]['signalDescription'] else: self.desc = '' - self.conversion = info['CCBlock'][dataGroup][channelGroup][channelNumber] + self.conversion = info['CCBlock'][data_group][channel_group][channel_number] def __str__(self): output = [self.channelNumber, ' ', self.name, ' ', self.signalDataType, ' ', @@ -1238,28 +1239,28 @@ def __str__(self): self.byteOffset, ' ', 'unit ', self.unit, 'description ', self.desc] return ''.join(output) - def changeChannelName(self, channelGroup): + def change_channel_name(self, channel_group): """ In case of duplicate channel names within several channel groups for unsorted data, rename channel name Parameters ------------ - channelGroup : int - channelGroup bumber + channel_group : int + channelGroup number """ - self.name = '{0}_{1}'.format(self.name, channelGroup) + self.name = '{0}_{1}'.format(self.name, channel_group) self.recAttributeName = _convert_name(self.name) self.RecordFormat = (('{}_title'.format(self.recAttributeName), self.recAttributeName), self.dataFormat) -def _datatypeformat3(signalDataType, numberOfBytes, ByteOrder): +def _data_type_format3(signal_data_type, number_of_bytes, byte_order): """ function returning C format string from channel data type and number of bits Parameters ---------------- - signalDataType : int + signal_data_type : int channel data type according to specification - numberOfBytes : int + number_of_bytes : int number of bytes taken by channel data in a record Returns @@ -1267,66 +1268,66 @@ def _datatypeformat3(signalDataType, numberOfBytes, ByteOrder): dataType : str C format used by fread to read channel raw data """ - if signalDataType in (0, 9, 13): # unsigned - if numberOfBytes == 1: - dataType = 'B' - elif numberOfBytes == 2: - dataType = 'H' - elif numberOfBytes <= 4: - dataType = 'I' - elif numberOfBytes <= 8: - dataType = 'Q' + if signal_data_type in (0, 9, 13): # unsigned + if number_of_bytes == 1: + data_type = 'B' + elif number_of_bytes == 2: + data_type = 'H' + elif number_of_bytes <= 4: + data_type = 'I' + elif number_of_bytes <= 8: + data_type = 'Q' else: - warn('Unsupported number of bits for unsigned int {}'.format(signalDataType)) - - elif signalDataType in (1, 10, 14): # signed int - if numberOfBytes == 1: - dataType = 'b' - elif numberOfBytes == 2: - dataType = 'h' - elif numberOfBytes <= 4: - dataType = 'i' - elif numberOfBytes <= 8: - dataType = 'q' + warn('Unsupported number of bits for unsigned int {}'.format(signal_data_type)) + + elif signal_data_type in (1, 10, 14): # signed int + if number_of_bytes == 1: + data_type = 'b' + elif number_of_bytes == 2: + data_type = 'h' + elif number_of_bytes <= 4: + data_type = 'i' + elif number_of_bytes <= 8: + data_type = 'q' else: - warn('Unsupported number of bits for signed int {}'.format(signalDataType)) + warn('Unsupported number of bits for signed int {}'.format(signal_data_type)) - elif signalDataType in (2, 3, 11, 12, 15, 16): # floating point - if numberOfBytes == 4: - dataType = 'f' - elif numberOfBytes == 8: - dataType = 'd' + elif signal_data_type in (2, 3, 11, 12, 15, 16): # floating point + if number_of_bytes == 4: + data_type = 'f' + elif number_of_bytes == 8: + data_type = 'd' else: - warn('Unsupported number of bit for floating point {}'.format(signalDataType)) + warn('Unsupported number of bit for floating point {}'.format(signal_data_type)) - elif signalDataType == 7: # string - dataType = str(numberOfBytes) + 's' - elif signalDataType == 8: # array of bytes - dataType = str(numberOfBytes) + 's' + elif signal_data_type == 7: # string + data_type = str(number_of_bytes) + 's' + elif signal_data_type == 8: # array of bytes + data_type = str(number_of_bytes) + 's' else: - warn('Unsupported Signal Data Type {0} nBits {1}'.format(signalDataType, numberOfBytes)) + warn('Unsupported Signal Data Type {0} nBits {1}'.format(signal_data_type, number_of_bytes)) # deal with byte order - if signalDataType in (0, 1, 2, 3): - if ByteOrder: - dataType = '>{}'.format(dataType) + if signal_data_type in (0, 1, 2, 3): + if byte_order: + data_type = '>{}'.format(data_type) else: - dataType = '<{}'.format(dataType) - elif signalDataType in (13, 14, 15, 16): # low endian - dataType = '<{}'.format(dataType) - elif signalDataType in (9, 10, 11, 12): # big endian - dataType = '>{}'.format(dataType) + data_type = '<{}'.format(data_type) + elif signal_data_type in (13, 14, 15, 16): # low endian + data_type = '<{}'.format(data_type) + elif signal_data_type in (9, 10, 11, 12): # big endian + data_type = '>{}'.format(data_type) - return dataType + return data_type -def _arrayformat3(signalDataType, numberOfBytes, ByteOrder): +def _array_format3(signal_data_type, number_of_bytes, byte_order): """ function returning numpy style string from channel data type and number of bits Parameters ---------------- - signalDataType : int + signal_data_type : int channel data type according to specification - numberOfBytes : int + number_of_bytes : int number of bytes taken by channel data in a record Returns @@ -1336,55 +1337,55 @@ def _arrayformat3(signalDataType, numberOfBytes, ByteOrder): """ # Formats used by numpy - if signalDataType in (0, 9, 13): # unsigned - if numberOfBytes == 1: - dataType = 'u1' - elif numberOfBytes == 2: - dataType = 'u2' - elif numberOfBytes <= 4: - dataType = 'u4' - elif numberOfBytes <= 8: - dataType = 'u8' + if signal_data_type in (0, 9, 13): # unsigned + if number_of_bytes == 1: + data_type = 'u1' + elif number_of_bytes == 2: + data_type = 'u2' + elif number_of_bytes <= 4: + data_type = 'u4' + elif number_of_bytes <= 8: + data_type = 'u8' else: - warn('Unsupported number of bits for unsigned int {} nBits '.format(signalDataType, numberOfBytes)) - - elif signalDataType in (1, 10, 14): # signed int - if numberOfBytes == 1: - dataType = 'i1' - elif numberOfBytes == 2: - dataType = 'i2' - elif numberOfBytes <= 4: - dataType = 'i4' - elif numberOfBytes <= 8: - dataType = 'i8' + warn('Unsupported number of bits for unsigned int {} nBits '.format(signal_data_type, number_of_bytes)) + + elif signal_data_type in (1, 10, 14): # signed int + if number_of_bytes == 1: + data_type = 'i1' + elif number_of_bytes == 2: + data_type = 'i2' + elif number_of_bytes <= 4: + data_type = 'i4' + elif number_of_bytes <= 8: + data_type = 'i8' else: - warn('Unsupported number of bits for signed int {0} nBits {1}'.format(signalDataType, numberOfBytes)) + warn('Unsupported number of bits for signed int {0} nBits {1}'.format(signal_data_type, number_of_bytes)) - elif signalDataType in (2, 3, 11, 12, 15, 16): # floating point - if numberOfBytes == 4: - dataType = 'f4' - elif numberOfBytes == 8: - dataType = 'f8' + elif signal_data_type in (2, 3, 11, 12, 15, 16): # floating point + if number_of_bytes == 4: + data_type = 'f4' + elif number_of_bytes == 8: + data_type = 'f8' else: - warn('Unsupported number of bit for floating point {0} nBits {1}'.format(signalDataType, numberOfBytes)) + warn('Unsupported number of bit for floating point {0} nBits {1}'.format(signal_data_type, number_of_bytes)) - elif signalDataType == 7: # string - dataType = 'S{}'.format(numberOfBytes) # not directly processed - elif signalDataType == 8: # array of bytes - dataType = 'V{}'.format(numberOfBytes) # not directly processed + elif signal_data_type == 7: # string + data_type = 'S{}'.format(number_of_bytes) # not directly processed + elif signal_data_type == 8: # array of bytes + data_type = 'V{}'.format(number_of_bytes) # not directly processed else: - warn('Unsupported Signal Data Type {0} nBits {1}'.format(signalDataType, numberOfBytes)) + warn('Unsupported Signal Data Type {0} nBits {1}'.format(signal_data_type, number_of_bytes)) - nativeDataType = dataType + native_data_type = data_type # deal with byte order - if signalDataType in (0, 1, 2, 3): - if ByteOrder: - dataType = '>{}'.format(dataType) + if signal_data_type in (0, 1, 2, 3): + if byte_order: + data_type = '>{}'.format(data_type) else: - dataType = '<{}'.format(dataType) - elif signalDataType in (13, 14, 15, 16): # low endian - dataType = '<{}'.format(dataType) - elif signalDataType in (9, 10, 11, 12): # big endian - dataType = '>{}'.format(dataType) + data_type = '<{}'.format(data_type) + elif signal_data_type in (13, 14, 15, 16): # low endian + data_type = '<{}'.format(data_type) + elif signal_data_type in (9, 10, 11, 12): # big endian + data_type = '>{}'.format(data_type) - return (dataType, nativeDataType) + return (data_type, native_data_type) diff --git a/mdfreader/mdf.py b/mdfreader/mdf.py index 46101df..225c368 100644 --- a/mdfreader/mdf.py +++ b/mdfreader/mdf.py @@ -115,7 +115,7 @@ def __init__(self, fileName=None, channelList=None, convertAfterRead=True, If many float are stored in file, you can gain from 3 to 4 times memory footprint To calculate value from channel, you can then use - method .getChannelData() + method .get_channel_data() filterChannelNames : bool, optional flag to filter long channel names from its module names @@ -221,18 +221,18 @@ def add_channel(self, channel_name, data, master_channel, master_type=1, unit='' self[channel_name]['conversion']['parameters']['cc_ref'] = \ conversion['cc_ref'] if info is not None: # axis from CABlock - CABlock = info + ca_block = info axis = [] - while 'CABlock' in CABlock: - CABlock = CABlock['CABlock'] - if 'ca_axis_value' in CABlock: - if type(CABlock['ca_dim_size']) is list: + while 'CABlock' in ca_block: + ca_block = ca_block['CABlock'] + if 'ca_axis_value' in ca_block: + if type(ca_block['ca_dim_size']) is list: index = 0 - for ndim in CABlock['ca_dim_size']: - axis.append(tuple(CABlock['ca_axis_value'][index:index+ndim])) + for ndim in ca_block['ca_dim_size']: + axis.append(tuple(ca_block['ca_axis_value'][index:index+ndim])) index += ndim else: - axis = CABlock['ca_axis_value'] + axis = ca_block['ca_axis_value'] self[channel_name]['axis'] = axis if identifier is not None: self[channel_name]['id'] = identifier @@ -322,7 +322,10 @@ def get_channel_unit(self, channel_name): """ temp = self._get_channel_field(channel_name, field=unitField) if isinstance(temp, (dict, defaultdict)): - temp = temp['Comment'] + try: + return temp['Comment'] + except KeyError: + return '' return temp def get_channel_desc(self, channel_name): @@ -552,8 +555,7 @@ def _channel_in_mdf(self, channel_name): ------- bool """ - return channel_name in self.masterChannelList[masterField] \ - or channel_name in self.masterChannelList + return channel_name in self.masterChannelList[masterField] or channel_name in self.masterChannelList def add_metadata(self, author='', organisation='', project='', subject='', comment='', date='', time=''): @@ -615,7 +617,7 @@ def __str__(self): except: pass output.append('\n ') - data = self.getChannelData(c) + data = self.get_channel_data(c) # not byte, impossible to represent if data.dtype.kind != 'V': output.append(array_repr(data[:], diff --git a/mdfreader/mdf3reader.py b/mdfreader/mdf3reader.py index e005829..d7ca0e9 100644 --- a/mdfreader/mdf3reader.py +++ b/mdfreader/mdf3reader.py @@ -34,7 +34,7 @@ from warnings import simplefilter from .mdf import MdfSkeleton, _open_mdf, \ dataField, conversionField, idField, CompressedData -from .mdfinfo3 import info3 +from .mdfinfo3 import Info3 from .channel import Channel3 if os.name == 'posix': from os import getlogin @@ -46,150 +46,150 @@ chunk_size_reading = 100000000 # reads by chunk of 100Mb, can be tuned for best performance -def linearConv(data, conv): # 0 Parametric, Linear: Physical =Integer*P2 + P1 +def _linear_conversion(data, conversion): # 0 Parametric, Linear: Physical =Integer*P2 + P1 """ apply linear conversion to data Parameters ---------------- data : numpy 1D array raw data to be converted to physical value - conv : mdfinfo3.info3 conversion block ('CCBlock') dict + conversion : mdfinfo3.info3 conversion block ('CCBlock') dict Returns ----------- converted data to physical value """ - if conv['P2'] == 1.0 and conv['P1'] in (0.0, -0.0): + if conversion['P2'] == 1.0 and conversion['P1'] in (0.0, -0.0): return data # keeps dtype probably more compact than float64 else: - return data * conv['P2'] + conv['P1'] + return data * conversion['P2'] + conversion['P1'] -def tabInterpConv(data, conv): # 1 Tabular with interpolation +def _tab_interp_conversion(data, conversion): # 1 Tabular with interpolation """ apply Tabular interpolation conversion to data Parameters ---------------- data : numpy 1D array raw data to be converted to physical value - conv : mdfinfo3.info3 conversion block ('CCBlock') dict + conversion : mdfinfo3.info3 conversion block ('CCBlock') dict Returns ----------- converted data to physical value """ tmp = array([(key, val['int'], val['phys']) - for (key, val) in conv.items()]) + for (key, val) in conversion.items()]) return interp(data, tmp[:, 1], tmp[:, 2]) -def tabConv(data, conv): # 2 Tabular +def _tab_conversion(data, conversion): # 2 Tabular """ apply Tabular conversion to data Parameters ---------------- data : numpy 1D array raw data to be converted to physical value - conv : mdfinfo3.info3 conversion block ('CCBlock') dict + conversion : mdfinfo3.info3 conversion block ('CCBlock') dict Returns ----------- converted data to physical value """ tmp = array([(key, val['int'], val['phys']) - for (key, val) in conv.items()]) + for (key, val) in conversion.items()]) indexes = searchsorted(tmp[:, 1], data) return tmp[indexes, 2] -def polyConv(data, conv): # 6 Polynomial +def _polynomial_conversion(data, conversion): # 6 Polynomial """ apply polynomial conversion to data Parameters ---------------- data : numpy 1D array raw data to be converted to physical value - conv : mdfinfo3.info3 conversion block ('CCBlock') dict + conversion : mdfinfo3.info3 conversion block ('CCBlock') dict Returns ----------- converted data to physical value """ - return (conv['P2'] - conv['P4'] * (data - conv['P5'] - conv['P6'])) \ - / (conv['P3'] * (data - conv['P5'] - conv['P6']) - conv['P1']) + return (conversion['P2'] - conversion['P4'] * (data - conversion['P5'] - conversion['P6'])) \ + / (conversion['P3'] * (data - conversion['P5'] - conversion['P6']) - conversion['P1']) -def expConv(data, conv): # 7 Exponential +def _exponential_conversion(data, conversion): # 7 Exponential """ apply exponential conversion to data Parameters ---------------- data : numpy 1D array raw data to be converted to physical value - conv : mdfinfo3.info3 conversion block ('CCBlock') dict + conversion : mdfinfo3.info3 conversion block ('CCBlock') dict Returns ----------- converted data to physical value """ - if conv['P4'] == 0 and conv['P1'] != 0 and conv['P2'] != 0: - return exp(((data - conv['P7']) * conv['P6'] - conv['P3']) - / conv['P1']) / conv['P2'] - elif conv['P1'] == 0 and conv['P4'] != 0 and conv['P5'] != 0: - return exp((conv['P3'] / (data - conv['P7']) - conv['P6']) - / conv['P4']) / conv['P5'] + if conversion['P4'] == 0 and conversion['P1'] != 0 and conversion['P2'] != 0: + return exp(((data - conversion['P7']) * conversion['P6'] - conversion['P3']) + / conversion['P1']) / conversion['P2'] + elif conversion['P1'] == 0 and conversion['P4'] != 0 and conversion['P5'] != 0: + return exp((conversion['P3'] / (data - conversion['P7']) - conversion['P6']) + / conversion['P4']) / conversion['P5'] else: warn('Non possible exponential parameters for channel') -def logConv(data, conv): # 8 Logarithmic +def _log_conversion(data, conversion): # 8 Logarithmic """ apply logarithmic conversion to data Parameters ---------------- data : numpy 1D array raw data to be converted to physical value - conv : mdfinfo3.info3 conversion block ('CCBlock') dict + conversion : mdfinfo3.info3 conversion block ('CCBlock') dict Returns ----------- converted data to physical value """ - if conv['P4'] == 0 and conv['P1'] != 0 and conv['P2'] != 0: - return log(((data - conv['P7']) * conv['P6'] - conv['P3']) - / conv['P1']) / conv['P2'] - elif conv['P1'] == 0 and conv['P4'] != 0 and conv['P5'] != 0: - return log((conv['P3'] / (data - conv['P7']) - conv['P6']) - / conv['P4']) / conv['P5'] + if conversion['P4'] == 0 and conversion['P1'] != 0 and conversion['P2'] != 0: + return log(((data - conversion['P7']) * conversion['P6'] - conversion['P3']) + / conversion['P1']) / conversion['P2'] + elif conversion['P1'] == 0 and conversion['P4'] != 0 and conversion['P5'] != 0: + return log((conversion['P3'] / (data - conversion['P7']) - conversion['P6']) + / conversion['P4']) / conversion['P5'] else: warn('Non possible logarithmic conversion parameters for channel') -def rationalConv(data, conv): # 9 rational +def _rational_conversion(data, conversion): # 9 rational """ apply rational conversion to data Parameters ---------------- data : numpy 1D array raw data to be converted to physical value - conv : mdfinfo3.info3 conversion block ('CCBlock') dict + conversion : mdfinfo3.info3 conversion block ('CCBlock') dict Returns ----------- converted data to physical value """ - return (conv['P1'] * data * data + conv['P2'] * data + conv['P3'])\ - / (conv['P4'] * data * data + conv['P5'] * data + conv['P6']) + return (conversion['P1'] * data * data + conversion['P2'] * data + conversion['P3'])\ + / (conversion['P4'] * data * data + conversion['P5'] * data + conversion['P6']) -def formulaConv(data, conv): # 10 Text Formula +def _formula_conversion(data, conversion): # 10 Text Formula """ apply formula conversion to data Parameters ---------------- data : numpy 1D array raw data to be converted to physical value - conv : mdfinfo3.info3 conversion block ('CCBlock') dict + conversion : mdfinfo3.info3 conversion block ('CCBlock') dict Returns ----------- @@ -202,7 +202,7 @@ def formulaConv(data, conv): # 10 Text Formula try: from sympy import lambdify, symbols X = symbols('X') # variable is X - formula = conv['textFormula'] + formula = conversion['textFormula'] # remove trailing text after 0 formula = formula[:formula.find('\x00')] # adapt ASAM-MCD2 syntax to sympy @@ -211,49 +211,49 @@ def formulaConv(data, conv): # 10 Text Formula expr = lambdify(X, formula, modules='numpy', dummify=False) return expr(data) except: - warn('Failed to convert formulae ' + conv['textFormula'] + + warn('Failed to convert formulae ' + conversion['textFormula'] + ' Sympy is correctly installed ?') -def textTableConv(data, conv): # 11 Text table +def _text_table_conversion(data, conversion): # 11 Text table """ apply text table conversion to data Parameters ---------------- data : numpy 1D array raw data to be converted to physical value - conv : mdfinfo3.info3 conversion block ('CCBlock') dict + conversion : mdfinfo3.info3 conversion block ('CCBlock') dict Returns ----------- converted data to physical value """ conversion_table = dict() - for pair in conv: - conversion_table[conv[pair]['int']] = conv[pair]['text'] + for pair in conversion: + conversion_table[conversion[pair]['int']] = conversion[pair]['text'] return vectorize(conversion_table.__getitem__)(data) -def textRangeTableConv(data, conv): # 12 Text range table +def _text_range_table_conversion(data, conversion): # 12 Text range table """ apply text range table conversion to data Parameters ---------------- data : numpy 1D array raw data to be converted to physical value - conv : mdfinfo3.info3 conversion block ('CCBlock') dict + conversion : mdfinfo3.info3 conversion block ('CCBlock') dict Returns ----------- converted data to physical value """ try: - npair = len(conv) - lower = [conv[pair]['lowerRange'] for pair in range(npair)] - upper = [conv[pair]['upperRange'] for pair in range(npair)] + n_pair = len(conversion) + lower = [conversion[pair]['lowerRange'] for pair in range(n_pair)] + upper = [conversion[pair]['upperRange'] for pair in range(n_pair)] text = {} - for pair in range(npair): - text[pair] = conv[pair]['Textrange'] + for pair in range(n_pair): + text[pair] = conversion[pair]['Textrange'] if text[pair] is None: continue if 'LINEAR_CONV' in text[pair]: # linear conversion from CANape @@ -264,14 +264,14 @@ def textRangeTableConv(data, conv): # 12 Text range table text[pair] = text[pair][left + 1: right].replace('{', '').replace('}', '') text[pair] = lambdify(X, text[pair], modules='numpy', dummify=False) temp = [] - for Lindex in range(len(data)): + for l_index in range(len(data)): value = text[0] # default value - for pair in range(1, npair): - if lower[pair] <= data[Lindex] <= upper[pair]: + for pair in range(1, n_pair): + if lower[pair] <= data[l_index] <= upper[pair]: value = text[pair] break if callable(value): - value = value(data[Lindex]) + value = value(data[l_index]) temp.append(value) try: temp = asarray(temp) # try to convert to numpy @@ -282,7 +282,7 @@ def textRangeTableConv(data, conv): # 12 Text range table warn('Failed to convert text to range table') -class record(list): +class Record(list): """ record class lists Channel classes, it is representing a channel group @@ -327,19 +327,19 @@ class record(list): readRecordBits(bita, channelSet=None) """ - def __init__(self, dataGroup, channelGroup): + def __init__(self, data_group, channel_group): self.CGrecordLength = 0 self.recordLength = 0 self.dataBlockLength = 0 self.numberOfRecords = 0 self.recordID = 0 self.recordIDnumber = 0 - self.dataGroup = dataGroup - self.channelGroup = channelGroup + self.dataGroup = data_group + self.channelGroup = channel_group self.numpyDataRecordFormat = [] self.dataRecordName = [] self.master = {} - self.master['name'] = 'master_{}'.format(dataGroup) + self.master['name'] = 'master_{}'.format(data_group) self.master['number'] = None self.recordToChannelMatching = {} self.channelNames = set() @@ -351,7 +351,7 @@ def __repr__(self): output.append('Channels :\n') for chan in self.channelNames: output.append(''.join([chan, '\n'])) - output.append('Datagroup number : {}\n'.format(self.dataGroup)) + output.append('Data group number : {}\n'.format(self.dataGroup)) if self.master['name'] is not None: output.append(''.join(['Master channel : ', self.master['name'], '\n'])) output.append('Numpy records format : \n') @@ -359,21 +359,20 @@ def __repr__(self): output.append('{}\n'.format(record)) return ''.join(output) - def addChannel(self, info, channelNumber): + def add_channel(self, info, channel_number): """ add a channel in class Parameters ---------------- info : mdfinfo3.info3 class - channelNumber : int + channel_number : int channel number in mdfinfo3.info3 class """ - self.append(Channel3(info, self.dataGroup, self.channelGroup, - channelNumber, self.recordIDnumber)) + self.append(Channel3(info, self.dataGroup, self.channelGroup, channel_number, self.recordIDnumber)) self.channelNames.add(self[-1].name) - def loadInfo(self, info): + def load_info(self, info): """ gathers records related from info class Parameters @@ -392,8 +391,7 @@ def loadInfo(self, info): self.dataBlockLength = (self.CGrecordLength + 1) * self.numberOfRecords embedding_channel = None for channelNumber in range(info['CGBlock'][self.dataGroup][self.channelGroup]['numberOfChannels']): - channel = Channel3(info, self.dataGroup, self.channelGroup, - channelNumber, self.recordIDnumber) + channel = Channel3(info, self.dataGroup, self.channelGroup, channelNumber, self.recordIDnumber) if self.master['number'] is None or channel.channelType == 1: # master channel found self.master['name'] = channel.name self.master['number'] = channelNumber @@ -452,8 +450,8 @@ def loadInfo(self, info): # forces to use dataRead instead of numpy records. self.byte_aligned = False - def readSortedRecord(self, fid, pointer, channelSet=None): - """ reads record, only one channel group per datagroup + def read_sorted_record(self, fid, pointer, channel_set=None): + """ reads record, only one channel group per data group Parameters ---------------- @@ -461,7 +459,7 @@ def readSortedRecord(self, fid, pointer, channelSet=None): file identifier pointer position in file of data block beginning - channelSet : Set of str, optional + channel_set : Set of str, optional list of channel to read Returns @@ -479,46 +477,46 @@ def readSortedRecord(self, fid, pointer, channelSet=None): """ fid.seek(pointer) - nchunks = self.dataBlockLength // chunk_size_reading + 1 - chunk_length = self.dataBlockLength // nchunks - nrecord_chunk = chunk_length // self.CGrecordLength - chunks = [(nrecord_chunk, self.CGrecordLength * nrecord_chunk)] * nchunks - nrecord_chunk = self.numberOfRecords - nrecord_chunk * nchunks - if nrecord_chunk > 0: - chunks.append((nrecord_chunk, self.CGrecordLength * nrecord_chunk)) + n_chunks = self.dataBlockLength // chunk_size_reading + 1 + chunk_length = self.dataBlockLength // n_chunks + n_record_chunk = chunk_length // self.CGrecordLength + chunks = [(n_record_chunk, self.CGrecordLength * n_record_chunk)] * n_chunks + n_record_chunk = self.numberOfRecords - n_record_chunk * n_chunks + if n_record_chunk > 0: + chunks.append((n_record_chunk, self.CGrecordLength * n_record_chunk)) previous_index = 0 - if channelSet is None and not self.hiddenBytes and self.byte_aligned: + if channel_set is None and not self.hiddenBytes and self.byte_aligned: # reads all, quickest but memory consuming buf = recarray(self.numberOfRecords, dtype={'names': self.dataRecordName, 'formats': self.numpyDataRecordFormat}) # initialise array simplefilter('ignore', FutureWarning) - for nrecord_chunk, chunk_size in chunks: - buf[previous_index: previous_index + nrecord_chunk] = \ + for n_record_chunk, chunk_size in chunks: + buf[previous_index: previous_index + n_record_chunk] = \ fromstring(fid.read(chunk_size), dtype={'names': self.dataRecordName, 'formats': self.numpyDataRecordFormat}, - shape=nrecord_chunk) - previous_index += nrecord_chunk + shape=n_record_chunk) + previous_index += n_record_chunk return buf else: # reads only some channels from a sorted data block - if channelSet is None: - channelSet = self.channelNames + if channel_set is None: + channel_set = self.channelNames # memory efficient but takes time # are channelSet in this dataGroup - if len(channelSet & self.channelNames) > 0: + if len(channel_set & self.channelNames) > 0: # check if master channel is in the list - if not self.master['name'] in channelSet: - channelSet.add(self.master['name']) # adds master channel - recChan = [] - numpyDataRecordFormat = [] - dataRecordName = [] + if not self.master['name'] in channel_set: + channel_set.add(self.master['name']) # adds master channel + rec_chan = [] + numpy_data_record_format = [] + data_record_name = [] for channel in self: # list of Channels from channelSet - if channel.name in channelSet: - recChan.append(channel) - dataRecordName.append(channel.name) - numpyDataRecordFormat.append(channel.nativedataFormat) - rec = recarray(self.numberOfRecords, dtype={'names': dataRecordName, - 'formats': numpyDataRecordFormat}) + if channel.name in channel_set: + rec_chan.append(channel) + data_record_name.append(channel.name) + numpy_data_record_format.append(channel.nativedataFormat) + rec = recarray(self.numberOfRecords, dtype={'names': data_record_name, + 'formats': numpy_data_record_format}) try: # use rather cython compiled code for performance from dataRead import dataRead # converts data type from mdf 3.x to 4.x @@ -526,42 +524,42 @@ def readSortedRecord(self, fid, pointer, channelSet=None): 7: 6, 8: 10, 9: 1, 10: 3, 11: 5, 12: 5, 13: 0, 14: 2, 15: 4, 16: 4} - for nrecord_chunk, chunk_size in chunks: - bita = fid.read(chunk_size) - for id, chan in enumerate(recChan): - rec[chan.name][previous_index: previous_index + nrecord_chunk] = \ - dataRead(bytes(bita), + for n_record_chunk, chunk_size in chunks: + bit_stream = fid.read(chunk_size) + for id, chan in enumerate(rec_chan): + rec[chan.name][previous_index: previous_index + n_record_chunk] = \ + dataRead(bytes(bit_stream), chan.bitCount, - convertDataType3to4[chan.signalDataType], + convertDataType3to4[chan.signal_data_type], chan.nativedataFormat, - nrecord_chunk, + n_record_chunk, self.CGrecordLength, chan.bitOffset, chan.posByteBeg, chan.nBytes, 0) self[id].bit_masking_needed = False # masking already considered in dataRead - previous_index += nrecord_chunk + previous_index += n_record_chunk return rec except: warn('Unexpected error: {}'.format(exc_info())) warn('dataRead crashed, back to python data reading') - recordLength = self.recordIDnumber + self.CGrecordLength + record_length = self.recordIDnumber + self.CGrecordLength for r in range(self.numberOfRecords): # for each record, - buf = fid.read(recordLength) - for channel in recChan: + buf = fid.read(record_length) + for channel in rec_chan: rec[channel.name][r] = \ channel.CFormat.unpack(buf[channel.posByteBeg: channel.posByteEnd])[0] return rec.view(recarray) - def readRecordBuf(self, buf, channelSet=None): + def read_record_buf(self, buf, channel_set=None): """ read stream of record bytes Parameters ---------------- buf : stream stream of bytes read in file - channelSet : Set of str, optional + channel_set : Set of str, optional list of channel to read Returns @@ -571,23 +569,23 @@ def readRecordBuf(self, buf, channelSet=None): """ temp = {} - if channelSet is None: - channelSet = self.channelNames + if channel_set is None: + channel_set = self.channelNames for Channel in self: # list of channel classes from channelSet - if Channel.name in channelSet: + if Channel.name in channel_set: temp[self.recordToChannelMatching[Channel.name]] = \ Channel.CFormat.unpack(buf[Channel.posByteBeg: Channel.posByteEnd])[0] return temp # returns dictionary of channel with its corresponding values - def readRecordBits(self, bita, channelSet=None): + def read_record_bits(self, bit_stream, channel_set=None): """ read stream of record bits by bits in case of not aligned or hidden bytes Parameters ---------------- - buf : stream + bit_stream : stream stream of bytes read in file - channelSet : Set of str, optional + channel_set : Set of str, optional list of channel to read Returns @@ -598,43 +596,43 @@ def readRecordBits(self, bita, channelSet=None): """ from bitarray import bitarray B = bitarray(endian="little") # little endian by default - B.frombytes(bytes(bita)) + B.frombytes(bytes(bit_stream)) - def signedInt(temp, extension): + def signed_int(temp, extension): """ extend bits of signed data managing two's complement """ extension.setall(False) - extensionInv = bitarray(extension, endian='little') - extensionInv.setall(True) - signBit = temp[-1] - if not signBit: # positive value, extend with 0 + extension_inv = bitarray(extension, endian='little') + extension_inv.setall(True) + sign_bit = temp[-1] + if not sign_bit: # positive value, extend with 0 temp.extend(extension) else: # negative value, extend with 1 - signBit = temp.pop(-1) - temp.extend(extensionInv) - temp.append(signBit) + sign_bit = temp.pop(-1) + temp.extend(extension_inv) + temp.append(sign_bit) return temp # read data temp = {} - if channelSet is None: - channelSet = self.channelNames + if channel_set is None: + channel_set = self.channelNames for Channel in self: # list of channel classes from channelSet - if Channel.name in channelSet: + if Channel.name in channel_set: temp[Channel.name] = B[Channel.posBitBeg: Channel.posBitEnd] nbytes = len(temp[Channel.name].tobytes()) if not nbytes == Channel.nBytes: byte = bitarray(8 * (Channel.nBytes - nbytes), endian='little') byte.setall(False) - if Channel.signalDataType not in (1, 10, 14): # not signed integer + if Channel.signal_data_type not in (1, 10, 14): # not signed integer temp[Channel.name].extend(byte) else: # signed integer (two's complement), keep sign bit and extend with bytes - temp[Channel.name] = signedInt(temp[Channel.name], byte) - nTrailBits = Channel.nBytes*8 - Channel.bitCount - if Channel.signalDataType in (1, 10, 14) and \ + temp[Channel.name] = signed_int(temp[Channel.name], byte) + n_trail_bits = Channel.nBytes*8 - Channel.bitCount + if Channel.signal_data_type in (1, 10, 14) and \ nbytes == Channel.nBytes and \ - nTrailBits > 0: # Ctype byte length but signed integer - trailBits = bitarray(nTrailBits, endian='little') - temp[Channel.name] = signedInt(temp[Channel.name], trailBits) + n_trail_bits > 0: # Ctype byte length but signed integer + trail_bits = bitarray(n_trail_bits, endian='little') + temp[Channel.name] = signed_int(temp[Channel.name], trail_bits) if 's' not in Channel.dataFormat: temp[Channel.name] = Channel.CFormat.unpack(temp[Channel.name].tobytes())[0] else: @@ -676,7 +674,7 @@ def __init__(self, fid, pointer): self.pointerToData = pointer self.BlockLength = 0 - def addRecord(self, record): + def add_record(self, record): """Adds a new record in DATA class dict Parameters @@ -688,56 +686,56 @@ def addRecord(self, record): self[record.recordID]['record'] = record self.BlockLength += record.dataBlockLength - def read(self, channelSet, filename): + def read(self, channel_set, file_name): """Reads data block Parameters ---------------- - channelSet : set of str, optional + channel_set : set of str, optional list of channel names - filename : str + file_name : str name of file """ # checks if file is closed if self.fid is None or self.fid.closed: - self.fid = open(filename, 'rb') + self.fid = open(file_name, 'rb') if len(self) == 1: # sorted dataGroup - recordID = list(self.keys())[0] - self[recordID]['data'] = \ - self.loadSorted(self[recordID]['record'], nameList=channelSet) + record_id = list(self.keys())[0] + self[record_id]['data'] = \ + self.load_sorted(self[record_id]['record'], name_list=channel_set) elif len(self) >= 2: # unsorted DataGroup - data = self.loadUnSorted(nameList=channelSet) - for recordID in list(self.keys()): - self[recordID]['data'] = {} - for channel in self[recordID]['record']: - self[recordID]['data'][channel.name] = \ - data[self[recordID]['record']. + data = self.load_unsorted(name_list=channel_set) + for record_id in list(self.keys()): + self[record_id]['data'] = {} + for channel in self[record_id]['record']: + self[record_id]['data'][channel.name] = \ + data[self[record_id]['record']. recordToChannelMatching[channel.name]] - def loadSorted(self, record, nameList=None): # reads sorted data + def load_sorted(self, record, name_list=None): # reads sorted data """Reads sorted data block from record definition Parameters ---------------- record: class channel group definition listing record channel classes - channelSet : set of str, optional + name_list : set of str, optional list of channel names Returns ----------- numpy recarray of data """ - return record.readSortedRecord(self.fid, self.pointerToData, nameList) + return record.read_sorted_record(self.fid, self.pointerToData, name_list) - def loadUnSorted(self, nameList=None): + def load_unsorted(self, name_list=None): """Reads unsorted data block from record definition Parameters ---------------- record: class channel group definition listing record channel classes - channelSet : set of str, optional + name_list : set of str, optional list of channel names Returns @@ -749,26 +747,26 @@ def loadUnSorted(self, nameList=None): # reads only the channels using offset functions, channel by channel. buf = defaultdict(list) position = 0 - recordIdCFormat = Struct('B') + record_id_c_format = Struct('B') # initialise data structure - for recordID in self: - for channelName in self[recordID]['record'].dataRecordName: + for record_id in self: + for channelName in self[record_id]['record'].dataRecordName: buf[channelName] = [] - if self[recordID]['record'].hiddenBytes or not self[recordID]['record'].byte_aligned: - for ind, chan in enumerate(self[recordID]['record']): + if self[record_id]['record'].hiddenBytes or not self[record_id]['record'].byte_aligned: + for ind, chan in enumerate(self[record_id]['record']): # will already extract bits, no need of masking later - self[recordID]['record'][ind].bit_masking_needed = False + self[record_id]['record'][ind].bit_masking_needed = False # read data while position < len(stream): - recordID = recordIdCFormat.unpack(stream[position:position + 1])[0] - if not self[recordID]['record'].hiddenBytes and self[recordID]['record'].byte_aligned: - temp = self[recordID]['record'].readRecordBuf( - stream[position:position + self[recordID]['record'].CGrecordLength + 1], nameList) + record_id = record_id_c_format.unpack(stream[position:position + 1])[0] + if not self[record_id]['record'].hiddenBytes and self[record_id]['record'].byte_aligned: + temp = self[record_id]['record'].read_record_buf( + stream[position:position + self[record_id]['record'].CGrecordLength + 1], name_list) else: # do not read bytes but bits in record - temp = self[recordID]['record'].readRecordBits( - stream[position:position + self[recordID]['record'].CGrecordLength + 1], nameList) + temp = self[record_id]['record'].read_record_bits( + stream[position:position + self[record_id]['record'].CGrecordLength + 1], name_list) # recordId is only unit8 - position += self[recordID]['record'].CGrecordLength + 1 + position += self[record_id]['record'].CGrecordLength + 1 for channelName in temp: buf[channelName].append(temp[channelName]) # to remove append # convert list to array @@ -777,7 +775,7 @@ def loadUnSorted(self, nameList=None): return buf -class mdf3(MdfSkeleton): +class Mdf3(MdfSkeleton): """ mdf file version 3.0 to 3.3 class @@ -805,45 +803,44 @@ class mdf3(MdfSkeleton): ------------ read3( fileName=None, info=None, multiProc=False, channelList=None, convertAfterRead=True) Reads mdf 3.x file data and stores it in dict - _getChannelData3(channelName) + _get_channel_data3(channelName) Returns channel numpy array - _convertChannel3(channelName) + _convert_channel3(channelName) converts specific channel from raw to physical data according to CCBlock information - _convertAllChannel3() + _convert_all_channel3() Converts all channels from raw data to converted data according to CCBlock information write3(fileName=None) Writes simple mdf 3.3 file """ - def read3(self, fileName=None, info=None, multiProc=False, channelList=None, - convertAfterRead=True, filterChannelNames=False, compression=False - , metadata=2): + def read3(self, file_name=None, info=None, multi_processed=False, channel_list=None, convert_after_read=True, + filter_channel_names=False, compression=False, metadata=2): """ Reads mdf 3.x file data and stores it in dict Parameters ---------------- - fileName : str, optional + file_name : str, optional file name info : mdfinfo3.info3 class info3 class containing all MDF Blocks - multiProc : bool + multi_processed : bool flag to activate multiprocessing of channel data conversion - channelList : list of str, optional + channel_list : list of str, optional list of channel names to be read If you use channelList, reading might be much slower but it will save you memory. Can be used to read big files - convertAfterRead : bool, optional + convert_after_read : bool, optional flag to convert channel after read, True by default If you use convertAfterRead by setting it to false, all data from channels will be kept raw, no conversion applied. If many float are stored in file, you can gain from 3 to 4 times memory footprint To calculate value from channel, you can then use method .getChannelData() - filterChannelNames : bool, optional + filter_channel_names : bool, optional flag to filter long channel names from its module names separated by '.' compression : bool, optional @@ -856,27 +853,27 @@ def read3(self, fileName=None, info=None, multiProc=False, channelList=None, 0: all metadata reading """ - self.multiProc = multiProc + self.multiProc = multi_processed if platform == 'win32': self.multiProc = False # no multiprocessing for windows platform if self.fileName is None and info is not None: self.fileName = info.fileName - elif fileName is not None and self.fileName is None: - self.fileName = fileName + elif file_name is not None and self.fileName is None: + self.fileName = file_name minimal = metadata # always reads minimum info by default - if channelList is None: - channelSetFile = None + if channel_list is None: + channel_set_file = None else: - channelSetFile = set(channelList) + channel_set_file = set(channel_list) minimal = 1 # reads at least CN to populate ChannelNamesByDG # Read information block from file if info is None: if self.info is None: - info = info3(self.fileName, fid=None, filterChannelNames=False, minimal=minimal) + info = Info3(self.fileName, fid=None, filterChannelNames=False, minimal=minimal) else: info = self.info @@ -896,72 +893,72 @@ def read3(self, fileName=None, info=None, multiProc=False, channelList=None, day, month, year = info['HDBlock']['Date'].split(':') ddate = '-'.join([year, month, day]) self.add_metadata(author=info['HDBlock']['Author'], - organisation=info['HDBlock']['Organization'], - project=info['HDBlock']['ProjectName'], - subject=info['HDBlock']['Subject'], comment=comment, - date=ddate, time=info['HDBlock']['Time']) + organisation=info['HDBlock']['Organization'], + project=info['HDBlock']['ProjectName'], + subject=info['HDBlock']['Subject'], comment=comment, + date=ddate, time=info['HDBlock']['Time']) data_groups = info['DGBlock'] # parse all data groups - if self._noDataLoading and channelList is not None: - data_groups = [self[channel][idField][0] for channel in channelList] + if self._noDataLoading and channel_list is not None: + data_groups = [self[channel][idField][0] for channel in channel_list] # Read data from file for dataGroup in data_groups: - channelSet = channelSetFile + channel_set = channel_set_file if info['DGBlock'][dataGroup]['numberOfChannelGroups'] > 0 and \ - (channelSet is None or - len(channelSet & info['ChannelNamesByDG'][dataGroup]) > 0): # data exists + (channel_set is None or + len(channel_set & info['ChannelNamesByDG'][dataGroup]) > 0): # data exists if minimal > 1 and not self._noDataLoading: # load CG, CN and CC block info - info.readCGBlock(info.fid, dataGroup, minimal=minimal) + info.read_cg_block(info.fid, dataGroup, minimal=minimal) # Pointer to data block - pointerToData = info['DGBlock'][dataGroup]['pointerToDataRecords'] + pointer_to_data = info['DGBlock'][dataGroup]['pointerToDataRecords'] if 'dataClass' not in info['DGBlock'][dataGroup]: - buf = DATA(info.fid, pointerToData) + buf = DATA(info.fid, pointer_to_data) for channelGroup in range(info['DGBlock'][dataGroup]['numberOfChannelGroups']): - temp = record(dataGroup, channelGroup) # create record class - temp.loadInfo(info) # load all info related to record + temp = Record(dataGroup, channelGroup) # create record class + temp.load_info(info) # load all info related to record if temp.numberOfRecords != 0: # continue if there are at least some records - buf.addRecord(temp) + buf.add_record(temp) if self._noDataLoading: self.info['DGBlock'][dataGroup]['dataClass'] = buf else: buf = self.info['DGBlock'][dataGroup]['dataClass'] - buf.read(channelSet, self.fileName) # reads datablock potentially containing several channel groups + buf.read(channel_set, self.fileName) # reads datablock potentially containing several channel groups channel_groups = buf - if self._noDataLoading and channelList is not None: + if self._noDataLoading and channel_list is not None: channel_groups = [info['CGBlock'][dataGroup][self[channel][idField][1]]['recordID'] - for channel in channelList] + for channel in channel_list] for recordID in channel_groups: if recordID in buf and 'record' in buf[recordID]: master_channel = buf[recordID]['record'].master['name'] - if channelList is None or not self._noDataLoading: + if channel_list is None or not self._noDataLoading: channels = (c for c in buf[recordID]['record'] - if channelSet is None or c.name in channelSet) + if channel_set is None or c.name in channel_set) else: channels = buf[recordID]['record'] - channels = [channels[self[channel][idField][2]] for channel in channelList] + channels = [channels[self[channel][idField][2]] for channel in channel_list] for chan in channels: # for each channel # in case record is used for several channels - if channelSet is None and not buf[recordID]['record'].hiddenBytes \ + if channel_set is None and not buf[recordID]['record'].hiddenBytes \ and buf[recordID]['record'].byte_aligned: - recordName = buf[recordID]['record'].\ + record_name = buf[recordID]['record'].\ recordToChannelMatching[chan.name] else: - recordName = chan.name - temp = buf[recordID]['data'][recordName] + record_name = chan.name + temp = buf[recordID]['data'][record_name] if len(temp) != 0: # Process concatenated bits inside uint8 if chan.bit_masking_needed: # if channel data do not use complete bytes - if chan.signalDataType in (0, 1, 9, 10, 13, 14): # integers + if chan.signal_data_type in (0, 1, 9, 10, 13, 14): # integers temp = right_shift(temp, chan.embedding_channel_bitOffset) mask = int(pow(2, chan.bitCount) - 1) # masks isBitUint8 temp = bitwise_and(temp, mask) @@ -974,18 +971,18 @@ def read3(self, fileName=None, info=None, multiProc=False, channelList=None, del buf if minimal > 1: # clean CN, CC and CG info to free memory - info.cleanDGinfo(dataGroup) + info.clean_dg_info(dataGroup) info.fid.close() # close file - if convertAfterRead and not compression: + if convert_after_read and not compression: self._noDataLoading = False - self._convertAllChannel3() + self._convert_all_channel3() - def _getChannelData3(self, channelName, raw_data=False): + def _get_channel_data3(self, channel_name, raw_data=False): """Returns channel numpy array Parameters ---------------- - channelName : str + channel_name : str channel name raw_data: bool flag to return non converted data @@ -999,25 +996,25 @@ def _getChannelData3(self, channelName, raw_data=False): ------ This method is the safest to get channel data as numpy array from 'data' dict key might contain raw data """ - if channelName in self: - vect = self.get_channel(channelName)[dataField] - if vect is None: # noDataLoading reading argument flag activated + if channel_name in self: + vector = self.get_channel(channel_name)[dataField] + if vector is None: # noDataLoading reading argument flag activated if self.info.fid is None or (self.info.fid is not None and self.info.fid.closed): (self.info.fid, self.info.fileName, zipfile) = _open_mdf(self.fileName) - self.read3(fileName=None, info=self.info, channelList=[channelName], convertAfterRead=False) + self.read3(file_name=None, info=self.info, channel_list=[channel_name], convert_after_read=False) if not raw_data: - return self._convert3(channelName, self.convert_tables) + return self._convert3(channel_name, self.convert_tables) else: - return self.get_channel(channelName)[dataField] + return self.get_channel(channel_name)[dataField] else: return None - def _convert3(self, channelName, convert_tables=False): + def _convert3(self, channel_name, convert_tables=False): """converts specific channel from raw to physical data according to CCBlock information Parameters ---------------- - channelName : str + channel_name : str Name of channel convert_tables : bool activates computation intensive loops for conversion with tables. Default is False @@ -1028,67 +1025,67 @@ def _convert3(self, channelName, convert_tables=False): returns numpy array converted to physical values according to conversion type """ - if self[channelName][dataField] is None: - vect = self[channelName][dataField] + if self[channel_name][dataField] is None: + vector = self[channel_name][dataField] else: - if isinstance(self[channelName][dataField], CompressedData): - vect = self[channelName][dataField].decompression() # uncompress blosc + if isinstance(self[channel_name][dataField], CompressedData): + vector = self[channel_name][dataField].decompression() # uncompress blosc else: - vect = self[channelName][dataField][:] # to have bcolz uncompressed data - if conversionField in self[channelName]: # there is conversion property - conversion = self[channelName][conversionField] + vector = self[channel_name][dataField][:] # to have bcolz uncompressed data + if conversionField in self[channel_name]: # there is conversion property + conversion = self[channel_name][conversionField] if conversion['type'] == 0: - return linearConv(vect, conversion['parameters']) + return _linear_conversion(vector, conversion['parameters']) elif conversion['type'] == 1: - return tabInterpConv(vect, conversion['parameters']) + return _tab_interp_conversion(vector, conversion['parameters']) elif conversion['type'] == 2: - return tabConv(vect, conversion['parameters']) + return _tab_conversion(vector, conversion['parameters']) elif conversion['type'] == 6: - return polyConv(vect, conversion['parameters']) + return _polynomial_conversion(vector, conversion['parameters']) elif conversion['type'] == 7: - return expConv(vect, conversion['parameters']) + return _exponential_conversion(vector, conversion['parameters']) elif conversion['type'] == 8: - return logConv(vect, conversion['parameters']) + return _log_conversion(vector, conversion['parameters']) elif conversion['type'] == 9: - return rationalConv(vect, conversion['parameters']) + return _rational_conversion(vector, conversion['parameters']) elif conversion['type'] == 10: - return formulaConv(vect, conversion['parameters']) + return _formula_conversion(vector, conversion['parameters']) elif conversion['type'] == 11 and convert_tables: - return textTableConv(vect, conversion['parameters']) + return _text_table_conversion(vector, conversion['parameters']) elif conversion['type'] == 12 and convert_tables: - return textRangeTableConv(vect, conversion['parameters']) + return _text_range_table_conversion(vector, conversion['parameters']) else: - return vect + return vector else: - return vect + return vector - def _convertChannel3(self, channelName): + def _convert_channel3(self, channel_name): """converts specific channel from raw to physical data according to CCBlock information Parameters ---------------- - channelName : str + channel_name : str Name of channel """ - self.set_channel_data(channelName, self._convert3(channelName, self.convert_tables)) - self.remove_channel_conversion(channelName) + self.set_channel_data(channel_name, self._convert3(channel_name, self.convert_tables)) + self.remove_channel_conversion(channel_name) - def _convertAllChannel3(self): + def _convert_all_channel3(self): """Converts all channels from raw data to converted data according to CCBlock information Converted data will take more memory. """ if self._noDataLoading: # no data loaded, load everything - self.read3(self.fileName, convertAfterRead=True) + self.read3(self.fileName, convert_after_read=True) else: for channel in self: - self._convertChannel3(channel) + self._convert_channel3(channel) - def write3(self, fileName=None): + def write3(self, file_name=None): """Writes simple mdf 3.3 file Parameters ---------------- - fileName : str, optional + file_name : str, optional Name of file If file name is not input, written file name will be the one read with appended '_new' string before extension @@ -1100,22 +1097,22 @@ def write3(self, fileName=None): # put master channel in first position for each datagroup if not already the case for master in self.masterChannelList: - masterList = sorted(self.masterChannelList[master]) - masterPosition = masterList.index(master) - masterList.pop(masterPosition) # remove master channel - masterList.insert(0, master) # insert at first position master channel - self.masterChannelList[master] = masterList + master_list = sorted(self.masterChannelList[master]) + master_position = master_list.index(master) + master_list.pop(master_position) # remove master channel + master_list.insert(0, master) # insert at first position master channel + self.masterChannelList[master] = master_list pointers = {} # records pointers of blocks when writing # write pointer of block and come back to current stream position - def writePointer(f, pointer, value): - currentPosition = f.tell() + def write_pointer(f, pointer, value): + current_position = f.tell() f.seek(pointer) f.write(pack('I', value)) - f.seek(currentPosition) + f.seek(current_position) - fid = open(fileName, 'wb') # buffering should automatically be set + fid = open(file_name, 'wb') # buffering should automatically be set # Starts first to write ID and header head = (b'MDF ', b'3.30 ', b'MDFreadr', 0, 0, 330, 28591, b'\0' * 32) @@ -1127,7 +1124,7 @@ def writePointer(f, pointer, value): pointers['HD']['DG'] = 68 pointers['HD']['TX'] = 72 pointers['HD']['PR'] = 76 - ndataGroup = len(self.masterChannelList) + n_data_group = len(self.masterChannelList) if self.file_metadata['author'] is not None: # Author try: author = '{:\x00<32.31}'.format(self.file_metadata['author']).encode('latin-1', 'ignore') @@ -1162,10 +1159,10 @@ def writePointer(f, pointer, value): # first Data block pointer, pointer to TX Block file comment, pointer to PR Block # number of data groups, date, time # Time Stamp, UTC time offset, Time quality, Timer identification - timeOffset = gmtime() - head = (b'HD', 208, 272, 0, 0, ndataGroup, - '{:\x00<10}'.format(strftime("%d:%m:%Y", timeOffset)).encode('latin-1'), - '{:\x00<8}'.format(strftime("%H:%M:%S", timeOffset)).encode('latin-1'), + time_offset = gmtime() + head = (b'HD', 208, 272, 0, 0, n_data_group, + '{:\x00<10}'.format(strftime("%d:%m:%Y", time_offset)).encode('latin-1'), + '{:\x00<8}'.format(strftime("%H:%M:%S", time_offset)).encode('latin-1'), author, organization, project, subject, int(time() * 1000000000), 1, 0, b'Local PC Reference Time ') @@ -1175,21 +1172,21 @@ def writePointer(f, pointer, value): pointers['DG'] = {} pointers['CG'] = {} pointers['CN'] = {} - dataGroup = 0 + data_group = 0 for masterChannel in self.masterChannelList: # writes dataGroup Block - pointers['DG'][dataGroup] = {} + pointers['DG'][data_group] = {} position = fid.tell() - if 0 < dataGroup: # not possible for first DG + if 0 < data_group: # not possible for first DG # previous datagroup pointer to this new datagroup - writePointer(fid, pointers['DG'][dataGroup - 1]['nextDG'], position) + write_pointer(fid, pointers['DG'][data_group - 1]['nextDG'], position) else: # first datagroup pointer in header block - writePointer(fid, pointers['HD']['DG'], position) - pointers['DG'][dataGroup]['nextDG'] = position + 4 - pointers['DG'][dataGroup]['CG'] = position + 8 - pointers['DG'][dataGroup]['data'] = position + 16 + write_pointer(fid, pointers['HD']['DG'], position) + pointers['DG'][data_group]['nextDG'] = position + 4 + pointers['DG'][data_group]['CG'] = position + 8 + pointers['DG'][data_group]['data'] = position + 16 # DG block size, pointer to next DataGroup, # pointer to channel group, pointer to trigger block, pointer to data block # number of channel group, number of record IDs, reserved @@ -1197,85 +1194,85 @@ def writePointer(f, pointer, value): fid.write(pack('<2sH4I2H4s', *head)) # sorted data so only one channel group - pointers['CG'][dataGroup] = {} + pointers['CG'][data_group] = {} # write first CG pointer in datagroup position = fid.tell() - writePointer(fid, pointers['DG'][dataGroup]['CG'], position) - pointers['CG'][dataGroup]['firstCN'] = position + 8 - pointers['CG'][dataGroup]['TX'] = position + 12 - pointers['CG'][dataGroup]['dataRecordSize'] = position + 20 - numChannels = len(self.masterChannelList[masterChannel]) - masterData = self.getChannelData(masterChannel) - nRecords = len(masterData) + write_pointer(fid, pointers['DG'][data_group]['CG'], position) + pointers['CG'][data_group]['firstCN'] = position + 8 + pointers['CG'][data_group]['TX'] = position + 12 + pointers['CG'][data_group]['dataRecordSize'] = position + 20 + num_channels = len(self.masterChannelList[masterChannel]) + master_data = self.get_channel_data(masterChannel) + n_records = len(master_data) # CG block size, pointer to next Channel Group # pointer to first channel block, pointer to TX block # No record ID no need for sorted data, Number of channels # Size of data record, Number of records, pointer to sample reduction block - head = (b'CG', 30, 0, 0, 0, 0, numChannels, 0, nRecords, 0) + head = (b'CG', 30, 0, 0, 0, 0, num_channels, 0, n_records, 0) fid.write(pack('<2sH3I3H2I', *head)) # Channel blocks writing - pointers['CN'][dataGroup] = {} - dataList = () - dataTypeList = '' - recordNumberOfBits = 0 - preceedingChannel = None - bitOffset = 0 - byteOffset = 0 + pointers['CN'][data_group] = {} + data_list = () + data_type_list = '' + record_number_of_bits = 0 + preceeding_channel = None + bit_offset = 0 + byte_offset = 0 # first channel bock pointer from CG position = fid.tell() - writePointer(fid, pointers['CG'][dataGroup]['firstCN'], position) + write_pointer(fid, pointers['CG'][data_group]['firstCN'], position) for channel in self.masterChannelList[masterChannel]: position = fid.tell() - pointers['CN'][dataGroup][channel] = {} - pointers['CN'][dataGroup][channel]['beginCN'] = position - pointers['CN'][dataGroup][channel]['nextCN'] = position + 4 - pointers['CN'][dataGroup][channel]['CC'] = position + 8 - pointers['CN'][dataGroup][channel]['TX'] = position + 16 - if preceedingChannel is not None: # not possible for first CN + pointers['CN'][data_group][channel] = {} + pointers['CN'][data_group][channel]['beginCN'] = position + pointers['CN'][data_group][channel]['nextCN'] = position + 4 + pointers['CN'][data_group][channel]['CC'] = position + 8 + pointers['CN'][data_group][channel]['TX'] = position + 16 + if preceeding_channel is not None: # not possible for first CN # pointer in previous CN - writePointer(fid, pointers['CN'][dataGroup][preceedingChannel]['nextCN'], - pointers['CN'][dataGroup][channel]['beginCN']) - preceedingChannel = channel + write_pointer(fid, pointers['CN'][data_group][preceeding_channel]['nextCN'], + pointers['CN'][data_group][channel]['beginCN']) + preceeding_channel = channel if channel not in set(self.masterChannelList): - masterFlag = 0 # data channel + master_flag = 0 # data channel else: - masterFlag = 1 # master channel + master_flag = 1 # master channel desc = self.get_channel_desc(channel) #if bitOffset exceeds two byte limit, we start using the byte offset field - if bitOffset > 0xFFFF: - bitOffset -= 0x10000 - byteOffset += 8192 - data = self.getChannelData(channel) # channel data + if bit_offset > 0xFFFF: + bit_offset -= 0x10000 + byte_offset += 8192 + data = self.get_channel_data(channel) # channel data temp = data - dataList = dataList + (temp, ) + data_list = data_list + (temp, ) cn_numpy_kind = data.dtype.kind - cn_numpy_itemsize = data.dtype.itemsize - numberOfBits = cn_numpy_itemsize * 8 + cn_numpy_item_size = data.dtype.itemsize + number_of_bits = cn_numpy_item_size * 8 if cn_numpy_kind in ('u', 'b'): - dataType = 0 + data_type = 0 elif cn_numpy_kind == 'i': - dataType = 1 + data_type = 1 elif cn_numpy_kind == 'f': - if cn_numpy_itemsize == 8: - dataType = 3 - elif cn_numpy_itemsize == 4: - dataType = 2 + if cn_numpy_item_size == 8: + data_type = 3 + elif cn_numpy_item_size == 4: + data_type = 2 else: raise Exception('Not recognized dtype') elif cn_numpy_kind in ('S', 'U', 'V'): - dataType = 7 + data_type = 7 else: raise Exception('Not recognized dtype') return data.dtype if data.dtype.kind not in ['S', 'U']: - dataTypeList = ''.join([dataTypeList, data.dtype.char]) + data_type_list = ''.join([data_type_list, data.dtype.char]) else: - dataTypeList = ''.join([dataTypeList, '{}s'.format(data.dtype.itemsize)]) - numberOfBits = 8 * data.dtype.itemsize - recordNumberOfBits += numberOfBits + data_type_list = ''.join([data_type_list, '{}s'.format(data.dtype.itemsize)]) + number_of_bits = 8 * data.dtype.itemsize + record_number_of_bits += number_of_bits if data.dtype.kind not in ['S', 'U']: - valueRangeValid = 1 + value_range_valid = 1 if len(data) > 0 and issubdtype(data.dtype, numpy_number): maximum = npmax(data) minimum = npmin(data) @@ -1283,10 +1280,10 @@ def writePointer(f, pointer, value): maximum = 0 minimum = 0 else: - valueRangeValid = 0 # No value range valid + value_range_valid = 0 # No value range valid minimum = 0 # Min value maximum = 0 # Max value - pointers['CN'][dataGroup][channel]['longChannelName'] = position + 218 + pointers['CN'][data_group][channel]['longChannelName'] = position + 218 # CN, block size # pointer to next channel block, pointer to conversion block # pointer to source depending block, pointer to dependency block @@ -1301,21 +1298,21 @@ def writePointer(f, pointer, value): description = '{:\x00<128.127}'.format(desc).encode('latin-1') except: description = b'\x00' * 128 - head = (b'CN', 228, 0, 0, 0, 0, 0, masterFlag, + head = (b'CN', 228, 0, 0, 0, 0, 0, master_flag, ('{:\x00<32.31}'.format(channel) + '\x00').encode('latin-1'), description, - bitOffset, numberOfBits, dataType, valueRangeValid, - minimum, maximum, 0, 0, 0, byteOffset) + bit_offset, number_of_bits, data_type, value_range_valid, + minimum, maximum, 0, 0, 0, byte_offset) fid.write(pack('<2sH5IH32s128s4H3d2IH', *head)) - bitOffset += numberOfBits + bit_offset += number_of_bits # TXblock for long channel name - writePointer(fid, pointers['CN'][dataGroup][channel]['longChannelName'], fid.tell()) + write_pointer(fid, pointers['CN'][data_group][channel]['longChannelName'], fid.tell()) head = (b'TX', len(channel) + 4 + 1, channel.encode('latin-1') + b'\x00') fid.write(pack('<2sH{}s'.format(len(channel)+1), *head)) # Conversion blocks writing - writePointer(fid, pointers['CN'][dataGroup][channel]['CC'], fid.tell()) + write_pointer(fid, pointers['CN'][data_group][channel]['CC'], fid.tell()) # channel description # conversion already done during reading # additional size information, not necessary for 65535 conversion type ? @@ -1324,23 +1321,23 @@ def writePointer(f, pointer, value): .encode('latin-1', 'replace')) except: unit = b'\x00' * 20 - head = (b'CC', 46, valueRangeValid, minimum, maximum, + head = (b'CC', 46, value_range_valid, minimum, maximum, unit, 65535, 0) fid.write(pack('<2shH2d20s2H', *head)) # number of channels in CG - currentPosition = fid.tell() - fid.seek(pointers['CG'][dataGroup]['dataRecordSize']) - fid.write(pack('H', int(recordNumberOfBits / 8))) # Size of data record - fid.seek(currentPosition) + current_position = fid.tell() + fid.seek(pointers['CG'][data_group]['dataRecordSize']) + fid.write(pack('H', int(record_number_of_bits / 8))) # Size of data record + fid.seek(current_position) # data writing # write data pointer in datagroup - writePointer(fid, pointers['DG'][dataGroup]['data'], fid.tell()) + write_pointer(fid, pointers['DG'][data_group]['data'], fid.tell()) # dumps data vector from numpy - fid.write(fromarrays(dataList).tobytes(order='F')) + fid.write(fromarrays(data_list).tobytes(order='F')) - dataGroup += 1 + data_group += 1 # print(pointers, file=stderr) fid.close() diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index 9a8b74b..abd5c3b 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -64,7 +64,7 @@ chunk_size_reading = 100000000 # reads by chunk of 100Mb, can be tuned for best performance -def _data_block(record, info, parent_block, channel_set=None, nrecords=None, sorted_flag=True, vlsd=False): +def _data_block(record, info, parent_block, channel_set=None, n_records=None, sorted_flag=True, vlsd=False): """ converts raw data into arrays Parameters @@ -76,7 +76,7 @@ def _data_block(record, info, parent_block, channel_set=None, nrecords=None, sor channel_set : set of str, optional defines set of channels to only read, can be slow but saves memory, for big files - nrecords: int, optional + n_records: int, optional number of records to read sorted_flag : bool, optional flag to know if data block is sorted (only one Channel Group in block) @@ -95,42 +95,43 @@ def _data_block(record, info, parent_block, channel_set=None, nrecords=None, sor This function will read DTBlock, RDBlock, DZBlock (compressed), RDBlock (VLSD), sorted or unsorted """ - if nrecords is None and hasattr(record, 'numberOfRecords'): - nrecords = record.numberOfRecords + if n_records is None and hasattr(record, 'numberOfRecords'): + n_records = record.numberOfRecords if parent_block['id'] in ('##DT', '##RD', b'##DT', b'##RD'): # normal data block if sorted_flag: if channel_set is None and not record.hiddenBytes and\ record.byte_aligned: # No channel list and length of records corresponds to C datatypes # for debugging purpose - # print(nrecords, record.numpyDataRecordFormat, record.dataRecordName) + # print(n_records, record.numpyDataRecordFormat, record.dataRecordName) return fromstring(parent_block['data'], dtype={'names': record.dataRecordName, 'formats': record.numpyDataRecordFormat}, - shape=nrecords) + shape=n_records) else: # record is not byte aligned or channelSet not None - return record.read_channels_from_bytes(parent_block['data'], info, channel_set, nrecords) + return record.read_channels_from_bytes(parent_block['data'], info, channel_set, n_records) else: # unsorted reading return _read_unsorted(record, info, parent_block, channel_set) elif parent_block['id'] in ('##SD', b'##SD'): - return _read_sdblock(record[record.VLSD[0]].signalDataType(info), parent_block['data'], + return _read_sdblock(record[record.VLSD[0]].signal_data_type(info), parent_block['data'], parent_block['length'] - 24) elif parent_block['id'] in ('##DZ', b'##DZ'): # zipped data block # uncompress data - parent_block['data'] = DZBlock.decompress_datablock(parent_block['data'], parent_block['dz_zip_type'], - parent_block['dz_zip_parameter'], parent_block['dz_org_data_length']) + parent_block['data'] = DZBlock.decompress_data_block(parent_block['data'], parent_block['dz_zip_type'], + parent_block['dz_zip_parameter'], + parent_block['dz_org_data_length']) if vlsd: # VLSD channel - return _read_sdblock(record[record.VLSD[0]].signalDataType(info), parent_block['data'], + return _read_sdblock(record[record.VLSD[0]].signal_data_type(info), parent_block['data'], parent_block['dz_org_data_length']) if channel_set is None and sorted_flag: # reads all blocks if sorted block and no channelSet defined if record.byte_aligned and not record.hiddenBytes: return fromstring(parent_block['data'], dtype={'names': record.dataRecordName, 'formats': record.numpyDataRecordFormat}, - shape=nrecords) + shape=n_records) else: - return record.read_channels_from_bytes(parent_block['data'], info, channel_set, nrecords) + return record.read_channels_from_bytes(parent_block['data'], info, channel_set, n_records) elif channel_set is not None and sorted_flag: # sorted data but channel list requested - return record.read_channels_from_bytes(parent_block['data'], info, channel_set, nrecords) + return record.read_channels_from_bytes(parent_block['data'], info, channel_set, n_records) else: # unsorted reading return _read_unsorted(record, info, parent_block, channel_set) @@ -139,38 +140,38 @@ def _read_unsorted(record, info, parent_block, channel_set=None): # reads only the channels using offset functions, channel by channel. buf = defaultdict(list) position = 0 - recordIdCFormat = record[list(record.keys())[0]]['record'].recordIDCFormat - recordIDsize = record[list(record.keys())[0]]['record'].recordIDsize + record_id_c_format = record[list(record.keys())[0]]['record'].recordIDCFormat + record_id_size = record[list(record.keys())[0]]['record'].recordIDsize VLSDStruct = Struct('I') # initialise data structure - for recordID in record: - for channelName in record[recordID]['record'].dataRecordName: + for record_id in record: + for channelName in record[record_id]['record'].dataRecordName: buf[channelName] = [] # empty(record.numberOfRecords,dtype=record[recordID]['record'].dataFormat) # index[channelName]=0 # read data while position < len(parent_block['data']): - recordID = recordIdCFormat.unpack(parent_block['data'][position:position + recordIDsize])[0] - if not record[recordID]['record'].Flags & 0b1: # not VLSD CG) - temp = record.read_record(recordID, info, parent_block['data'][position:position + record[recordID][ + record_id = record_id_c_format.unpack(parent_block['data'][position:position + record_id_size])[0] + if not record[record_id]['record'].Flags & 0b1: # not VLSD CG) + temp = record.read_record(record_id, info, parent_block['data'][position:position + record[record_id][ 'record'].CGrecordLength + 1], channel_set) - position += record[recordID]['record'].CGrecordLength + position += record[record_id]['record'].CGrecordLength for channelName in temp: buf[channelName].append(temp[channelName]) else: # VLSD CG - position += recordIDsize + position += record_id_size VLSDLen = VLSDStruct.unpack(parent_block['data'][position:position + 4])[0] # VLSD length position += 4 temp = parent_block['data'][position:position + VLSDLen - 1] - signalDataType = record[recordID]['record'].VLSD_CG[recordID]['channel'].signalDataType(info) - if signalDataType == 6: + signal_data_type = record[record_id]['record'].VLSD_CG[record_id]['channel'].signal_data_type(info) + if signal_data_type == 6: temp = temp.decode('ISO8859') - elif signalDataType == 7: + elif signal_data_type == 7: temp = temp.decode('utf-8') - elif signalDataType == 8: + elif signal_data_type == 8: temp = temp.decode('utf-16') - buf[record[recordID]['record'].VLSD_CG[recordID]['channelName']].append(temp) + buf[record[record_id]['record'].VLSD_CG[record_id]['channelName']].append(temp) position += VLSDLen # convert list to array for chan in buf: @@ -380,7 +381,7 @@ def load(self, record, info, name_list=None, sorted_flag=True, vlsd=False): temp = DZBlock() temp.read(self.fid) data_block.update(temp) - data_block['data'].extend(DZBlock.decompress_datablock( + data_block['data'].extend(DZBlock.decompress_data_block( self.fid.read(data_block['dz_data_length']), data_block['dz_zip_type'], data_block['dz_zip_parameter'], @@ -390,7 +391,7 @@ def load(self, record, info, name_list=None, sorted_flag=True, vlsd=False): else: data_block['id'] = '##{}'.format(data_block['dz_org_block_type'].decode('ASCII')) temps['data'] = _data_block(record, info, parent_block=data_block, channel_set=name_list, - nrecords=None, sorted_flag=sorted_flag, vlsd=vlsd) + n_records=None, sorted_flag=sorted_flag, vlsd=vlsd) else: for DL in temps['dl_data']: for pointer in temps['dl_data'][DL]: @@ -402,7 +403,7 @@ def load(self, record, info, name_list=None, sorted_flag=True, vlsd=False): temp = DZBlock() temp.read(self.fid) data_block.update(temp) - data_block['data'].extend(DZBlock.decompress_datablock( + data_block['data'].extend(DZBlock.decompress_data_block( self.fid.read(data_block['dz_data_length']), data_block['dz_zip_type'], data_block['dz_zip_parameter'], @@ -420,7 +421,7 @@ def load(self, record, info, name_list=None, sorted_flag=True, vlsd=False): # there could be more data than needed for the expected number of records nrecord_chunk = record.numberOfRecords - previous_index tmp = _data_block(record, info, parent_block=data_block, channel_set=name_list, - nrecords=nrecord_chunk, sorted_flag=sorted_flag, vlsd=vlsd) + n_records=nrecord_chunk, sorted_flag=sorted_flag, vlsd=vlsd) if 'data' not in temps: # initialise recarray temps['data'] = recarray(record.numberOfRecords, dtype=tmp.dtype) temps['data'][previous_index: previous_index + nrecord_chunk] = tmp @@ -439,37 +440,35 @@ def load(self, record, info, name_list=None, sorted_flag=True, vlsd=False): self.pointer_to_data = temps['hl_dl_first'] temps['data'] = self.load(record, info, name_list=name_list, sorted_flag=sorted_flag, vlsd=vlsd) elif temps['id'] in ('##DT', '##RD', b'##DT', b'##RD'): # normal sorted data block, direct read - temps['data'] = record.readSortedRecord(self.fid, info, channelSet=name_list) + temps['data'] = record.read_sorted_record(self.fid, info, channel_set=name_list) elif temps['id'] in ('##SD', b'##SD'): # VLSD temps['data'] = self.fid.read(temps['length'] - 24) - temps['data'] = _data_block(record, info, parent_block=temps, channel_set=name_list, nrecords=None, + temps['data'] = _data_block(record, info, parent_block=temps, channel_set=name_list, n_records=None, sorted_flag=sorted_flag) elif temps['id'] in ('##DZ', b'##DZ'): # zipped data block temp = DZBlock() temp.read(self.fid) temps.update(temp) temps['data'] = self.fid.read(temps['dz_data_length']) - temps['data'] = _data_block(record, info, parent_block=temps, channel_set=name_list, nrecords=None, + temps['data'] = _data_block(record, info, parent_block=temps, channel_set=name_list, n_records=None, sorted_flag=sorted_flag, vlsd=vlsd) else: raise Exception('unknown data block') return temps['data'] - def read_record(self, recordID, info, buf, channel_set=None): + def read_record(self, record_id, info, buf): """ read record from a buffer Parameters ---------------- - recordID : int + record_id : int record identifier info : class contains blocks buf : str buffer of data from file to be converted to channel raw data - channel_set : set of str - set of channel names to be read """ - return self[recordID]['record'].readRecordBuf(buf, info, channel_set) + return self[record_id]['record'].read_record_buf(buf, info) class Record(list): @@ -540,19 +539,19 @@ class Record(list): read_channels_from_bytes_fallback(bita, info, channel_set=None, nrecords=None, dtype=None, channels_indexes=None) """ - def __init__(self, dataGroup, channelGroup): + def __init__(self, data_group, channel_group): self.CGrecordLength = 0 self.recordLength = 0 self.numberOfRecords = 0 self.recordID = 0 self.recordIDsize = 0 self.recordIDCFormat = '' - self.dataGroup = dataGroup - self.channelGroup = channelGroup + self.dataGroup = data_group + self.channelGroup = channel_group self.numpyDataRecordFormat = [] self.dataRecordName = [] self.master = {} - self.master['name'] = 'master_{}'.format(dataGroup) + self.master['name'] = 'master_{}'.format(data_group) self.master['number'] = None self.Flags = 0 self.VLSD_CG = {} @@ -638,111 +637,112 @@ def load_info(self, info): self.MLSD = info['MLSD'] embedding_channel = None for channelNumber in info['CN'][self.dataGroup][self.channelGroup]: - Channel = Channel4() - Channel.set(info, self.dataGroup, self.channelGroup, channelNumber) - channelType = Channel.channelType(info) - dataFormat = Channel.dataFormat(info) - if channelType in (2, 3): # master channel found - if self.master['number'] is None or Channel.channelSyncType(info) == 1: + channel = Channel4() + channel.set(info, self.dataGroup, self.channelGroup, channelNumber) + channel_type = channel.channel_type(info) + data_format = channel.data_format(info) + if channel_type in (2, 3): # master channel found + if self.master['number'] is None or channel.channel_sync_type(info) == 1: # new master channel found # or more than 1 master channel, priority to time channel self.master['number'] = channelNumber - self.master['name'] = Channel.name - if channelType in (0, 1, 2, 4, 5): # not virtual channel - signalDataType = Channel.signalDataType(info) - if signalDataType == 13: + self.master['name'] = channel.name + if channel_type in (0, 1, 2, 4, 5): # not virtual channel + signal_data_type = channel.signal_data_type(info) + if signal_data_type == 13: for name in ('ms', 'minute', 'hour', 'day', 'month', 'year'): - Channel = Channel4() # new object otherwise only modified - Channel.setCANOpen(info, self.dataGroup, self.channelGroup, channelNumber, name) - self.append(Channel) + channel = Channel4() # new object otherwise only modified + channel.set_CANOpen(info, self.dataGroup, self.channelGroup, channelNumber, name) + self.append(channel) self.channelNames.add(name) self.dataRecordName.append(name) self.recordToChannelMatching[name] = name - self.numpyDataRecordFormat.append(Channel.dataFormat(info)) + self.numpyDataRecordFormat.append(channel.data_format(info)) self.recordLength += 7 self.CANOpen = 'date' embedding_channel = None - elif signalDataType == 14: + elif signal_data_type == 14: for name in ('ms', 'days'): - Channel = Channel4() - Channel.setCANOpen(info, self.dataGroup, self.channelGroup, channelNumber, name) - self.append(Channel) + channel = Channel4() + channel.set_CANOpen(info, self.dataGroup, self.channelGroup, channelNumber, name) + self.append(channel) self.channelNames.add(name) self.dataRecordName.append(name) self.recordToChannelMatching[name] = name - self.numpyDataRecordFormat.append(Channel.dataFormat(info)) + self.numpyDataRecordFormat.append(channel.data_format(info)) self.recordLength += 6 self.CANOpen = 'time' embedding_channel = None else: - self.append(Channel) - self.channelNames.add(Channel.name) + self.append(channel) + self.channelNames.add(channel.name) # Checking if several channels are embedded in bytes if len(self) > 1: # all channels are already ordered in record based on byte_offset # and bit_offset so just comparing with previous channel - Channel_posBitEnd = Channel.posBitEnd(info) - Channel_posBitBeg = Channel.posBitBeg(info) + channel_pos_bit_end = channel.pos_bit_end(info) + channel_pos_bit_beg = channel.pos_bit_beg(info) prev_chan = self[-2] - prev_chan_byteOffset = prev_chan.byteOffset - prev_chan_nBytes = prev_chan.nBytes - prev_chan_includes_curr_chan = Channel_posBitBeg >= 8 * prev_chan_byteOffset \ - and Channel_posBitEnd <= 8 * (prev_chan_byteOffset + prev_chan_nBytes) + prev_chan_byte_offset = prev_chan.byteOffset + prev_chan_n_bytes = prev_chan.nBytes + prev_chan_includes_curr_chan = channel_pos_bit_beg >= 8 * prev_chan_byte_offset \ + and channel_pos_bit_end <= 8 * (prev_chan_byte_offset + prev_chan_n_bytes) if embedding_channel is not None: embedding_channel_includes_curr_chan = \ - Channel_posBitEnd <= embedding_channel.posByteEnd(info) * 8 + channel_pos_bit_end <= embedding_channel.posByteEnd(info) * 8 else: embedding_channel_includes_curr_chan = False - if Channel.byteOffset >= prev_chan_byteOffset and \ - Channel_posBitBeg < 8 * (prev_chan_byteOffset + prev_chan_nBytes) < Channel_posBitEnd: + if channel.byteOffset >= prev_chan_byte_offset and \ + channel_pos_bit_beg < 8 * (prev_chan_byte_offset + + prev_chan_n_bytes) < channel_pos_bit_end: # not byte aligned self.byte_aligned = False if embedding_channel is not None and \ - Channel_posBitEnd > embedding_channel.posByteEnd(info) * 8: + channel_pos_bit_end > embedding_channel.posByteEnd(info) * 8: embedding_channel = None if prev_chan_includes_curr_chan or \ embedding_channel_includes_curr_chan: # bit(s) in byte(s) if embedding_channel is None and prev_chan_includes_curr_chan: embedding_channel = prev_chan # new embedding channel detected - if self.recordToChannelMatching: # not first channel - self.recordToChannelMatching[Channel.name] = \ + if self.recordToChannelMatching: # not first channel + self.recordToChannelMatching[channel.name] = \ self.recordToChannelMatching[prev_chan.name] else: # first channels - self.recordToChannelMatching[Channel.name] = Channel.name - self.numpyDataRecordFormat.append(dataFormat) - self.dataRecordName.append(Channel.name) - self.recordLength += Channel.nBytes + self.recordToChannelMatching[channel.name] = channel.name + self.numpyDataRecordFormat.append(data_format) + self.dataRecordName.append(channel.name) + self.recordLength += channel.nBytes if embedding_channel is None: # adding bytes - self.recordToChannelMatching[Channel.name] = Channel.name - self.numpyDataRecordFormat.append(dataFormat) - self.dataRecordName.append(Channel.name) - self.recordLength += Channel.nBytes + self.recordToChannelMatching[channel.name] = channel.name + self.numpyDataRecordFormat.append(data_format) + self.dataRecordName.append(channel.name) + self.recordLength += channel.nBytes if 'VLSD_CG' in info: # is there VLSD CG for recordID in info['VLSD_CG']: # look for VLSD CG Channel if info['VLSD_CG'][recordID]['cg_cn'] == (self.channelGroup, channelNumber): self.VLSD_CG[recordID] = info['VLSD_CG'][recordID] - self.VLSD_CG[recordID]['channel'] = Channel - self.VLSD_CG[recordID]['channelName'] = Channel.name + self.VLSD_CG[recordID]['channel'] = channel + self.VLSD_CG[recordID]['channelName'] = channel.name self[-1].VLSD_CG_Flag = True break - if channelType == 1: # VLSD channel - self.VLSD.append(Channel.channelNumber) - elif channelType in (3, 6): # virtual channel - self.append(Channel) # channel calculated based on record index later in conversion function - self.channelNames.add(Channel.name) - self.recordToChannelMatching[Channel.name] = Channel.name + if channel_type == 1: # VLSD channel + self.VLSD.append(channel.channelNumber) + elif channel_type in (3, 6): # virtual channel + self.append(channel) # channel calculated based on record index later in conversion function + self.channelNames.add(channel.name) + self.recordToChannelMatching[channel.name] = channel.name if info['CG'][self.dataGroup][self.channelGroup]['cg_invalid_bytes']: # invalid bytes existing self.CGrecordLength += info['CG'][self.dataGroup][self.channelGroup]['cg_invalid_bytes'] self.recordLength += info['CG'][self.dataGroup][self.channelGroup]['cg_invalid_bytes'] invalid_bytes = Channel4() - invalid_bytes.setInvalidBytes(info, self.dataGroup, self.channelGroup, channelNumber + 1) + invalid_bytes.set_invalid_bytes(info, self.dataGroup, self.channelGroup, channelNumber + 1) self.invalid_channel = invalid_bytes self.append(self.invalid_channel) self.channelNames.add(self.invalid_channel.name) self.recordToChannelMatching[self.invalid_channel.name] = \ self.invalid_channel.name - self.numpyDataRecordFormat.append(self.invalid_channel.dataFormat(info)) + self.numpyDataRecordFormat.append(self.invalid_channel.data_format(info)) self.dataRecordName.append(self.invalid_channel.name) # check for hidden bytes if self.CGrecordLength > self.recordLength: @@ -751,7 +751,7 @@ def load_info(self, info): elif self.CGrecordLength < self.recordLength: self.byte_aligned = False # forces to use dataRead instead of numpy records. - def readSortedRecord(self, fid, info, channelSet=None): + def read_sorted_record(self, fid, info, channel_set=None): """ reads record, only one channel group per datagroup Parameters @@ -760,7 +760,7 @@ def readSortedRecord(self, fid, info, channelSet=None): file identifier info info class - channelSet : set of str, optional + channel_set : set of str, optional set of channel to read Returns @@ -774,26 +774,26 @@ def readSortedRecord(self, fid, info, channelSet=None): However, in case of large file, you can use channelSet to load only interesting channels or only one channel on demand, but be aware it might be much slower. """ - if channelSet is None and self.byte_aligned and not self.hiddenBytes: + if channel_set is None and self.byte_aligned and not self.hiddenBytes: return self.read_all_channels_sorted_record(fid) else: # reads only some channels from a sorted data block - if channelSet is None or len(channelSet & self.channelNames) > 0: - return self.read_not_all_channels_sorted_record(fid, info, channelSet) + if channel_set is None or len(channel_set & self.channelNames) > 0: + return self.read_not_all_channels_sorted_record(fid, info, channel_set) def generate_chunks(self): """ calculate data split Returns -------- - (nrecord_chunk, chunk_size) + (n_record_chunk, chunk_size) """ - nchunks = (self.CGrecordLength * self.numberOfRecords) // chunk_size_reading + 1 - chunk_length = (self.CGrecordLength * self.numberOfRecords) // nchunks - nrecord_chunk = chunk_length // self.CGrecordLength - chunks = [(nrecord_chunk, self.CGrecordLength * nrecord_chunk)] * nchunks - nrecord_chunk = self.numberOfRecords - nrecord_chunk * nchunks - if nrecord_chunk > 0: - chunks.append((nrecord_chunk, self.CGrecordLength * nrecord_chunk)) + n_chunks = (self.CGrecordLength * self.numberOfRecords) // chunk_size_reading + 1 + chunk_length = (self.CGrecordLength * self.numberOfRecords) // n_chunks + n_record_chunk = chunk_length // self.CGrecordLength + chunks = [(n_record_chunk, self.CGrecordLength * n_record_chunk)] * n_chunks + n_record_chunk = self.numberOfRecords - n_record_chunk * n_chunks + if n_record_chunk > 0: + chunks.append((n_record_chunk, self.CGrecordLength * n_record_chunk)) return chunks def read_all_channels_sorted_record(self, fid): @@ -814,16 +814,16 @@ def read_all_channels_sorted_record(self, fid): buf = recarray(self.numberOfRecords, dtype={'names': self.dataRecordName, 'formats': self.numpyDataRecordFormat}) # initialise array simplefilter('ignore', FutureWarning) - for nrecord_chunk, chunk_size in chunks: - buf[previous_index: previous_index + nrecord_chunk] = \ + for n_record_chunk, chunk_size in chunks: + buf[previous_index: previous_index + n_record_chunk] = \ fromstring(fid.read(chunk_size), dtype={'names': self.dataRecordName, 'formats': self.numpyDataRecordFormat}, - shape=nrecord_chunk) - previous_index += nrecord_chunk + shape=n_record_chunk) + previous_index += n_record_chunk return buf - def read_not_all_channels_sorted_record(self, fid, info, channelSet): + def read_not_all_channels_sorted_record(self, fid, info, channel_set): """ reads channels from file listed in channelSet Parameters @@ -831,7 +831,7 @@ def read_not_all_channels_sorted_record(self, fid, info, channelSet): fid : file identifier info: info class - channelSet : set of str, optional + channel_set : set of str, optional set of channel to read Returns @@ -841,40 +841,39 @@ def read_not_all_channels_sorted_record(self, fid, info, channelSet): """ chunks = self.generate_chunks() previous_index = 0 - if channelSet is None: - channelSet = self.channelNames - if channelSet is not None and not self.master['name'] in channelSet: - channelSet.add(self.master['name']) # adds master channel - rec, channels_indexes = self.initialise_recarray(info, channelSet, self.numberOfRecords) + if channel_set is None: + channel_set = self.channelNames + if channel_set is not None and not self.master['name'] in channel_set: + channel_set.add(self.master['name']) # adds master channel + rec, channels_indexes = self.initialise_recarray(info, channel_set, self.numberOfRecords) if rec is not None: if dataRead_available: - for nrecord_chunk, chunk_size in chunks: - rec[previous_index: previous_index + nrecord_chunk] = \ - self.read_channels_from_bytes(fid.read(chunk_size), - info, channelSet, nrecord_chunk, + for n_record_chunk, chunk_size in chunks: + rec[previous_index: previous_index + n_record_chunk] = \ + self.read_channels_from_bytes(fid.read(chunk_size), info, channel_set, n_record_chunk, rec.dtype, channels_indexes) - previous_index += nrecord_chunk + previous_index += n_record_chunk return rec else: - for nrecord_chunk, chunk_size in chunks: - rec[previous_index: previous_index + nrecord_chunk] = \ - self.read_channels_from_bytes_fallback(fid.read(chunk_size), info, channelSet, nrecord_chunk, + for n_record_chunk, chunk_size in chunks: + rec[previous_index: previous_index + n_record_chunk] = \ + self.read_channels_from_bytes_fallback(fid.read(chunk_size), info, channel_set, n_record_chunk, rec.dtype, channels_indexes) - previous_index += nrecord_chunk + previous_index += n_record_chunk return rec else: return [] - def readRecordBuf(self, buf, info, channelSet=None): + def read_record_buf(self, buf, info, channel_set=None): """ read stream of record bytes Parameters ---------------- buf : stream stream of bytes read in file - info class + info: class contains blocks structure - channelSet : set of str, optional + channel_set : set of str, optional set of channel to read Returns @@ -884,15 +883,15 @@ def readRecordBuf(self, buf, info, channelSet=None): """ temp = {} - if channelSet is None: - channelSet = self.channelNames + if channel_set is None: + channel_set = self.channelNames for Channel in self: # list of channel classes from channelSet - if Channel.name in channelSet and not Channel.VLSD_CG_Flag: + if Channel.name in channel_set and not Channel.VLSD_CG_Flag: temp[Channel.name] = \ - Channel.CFormat(info).unpack(buf[Channel.posByteBeg(info):Channel.posByteEnd(info)])[0] + Channel.c_format_structure(info).unpack(buf[Channel.pos_byte_beg(info):Channel.pos_byte_end(info)])[0] return temp # returns dictionary of channel with its corresponding values - def initialise_recarray(self, info, channel_set, nrecords, dtype=None, channels_indexes=None): + def initialise_recarray(self, info, channel_set, n_records, dtype=None, channels_indexes=None): """ Initialise recarray Parameters @@ -900,7 +899,7 @@ def initialise_recarray(self, info, channel_set, nrecords, dtype=None, channels_ info: info class channel_set : set of str, optional set of channel to read - nrecords: int + n_records: int number of records dtype: numpy dtype, optional channels_indexes: list of int, optional @@ -911,7 +910,7 @@ def initialise_recarray(self, info, channel_set, nrecords, dtype=None, channels_ contains a matrix of raw data in a recarray (attributes corresponding to channel name) """ if dtype is not None and channels_indexes is not None: - return recarray(nrecords, dtype=dtype), channels_indexes + return recarray(n_records, dtype=dtype), channels_indexes else: if channel_set is None: channel_set = self.channelNames @@ -919,29 +918,29 @@ def initialise_recarray(self, info, channel_set, nrecords, dtype=None, channels_ names = [] channels_indexes = [] for chan in range(len(self)): - if self[chan].name in channel_set and self[chan].channelType(info) not in (3, 6): + if self[chan].name in channel_set and self[chan].channel_type(info) not in (3, 6): # not virtual channel and part of channelSet channels_indexes.append(chan) - formats.append(self[chan].nativedataFormat(info)) + formats.append(self[chan].native_data_format(info)) names.append(self[chan].name) if formats: - rec = recarray(nrecords, dtype={'names': names, 'formats': formats}) + rec = recarray(n_records, dtype={'names': names, 'formats': formats}) return rec, channels_indexes else: return None, [] - def read_channels_from_bytes(self, bita, info, channelSet=None, nrecords=None, - dtype=None, channels_indexes=None): + def read_channels_from_bytes(self, bit_stream, info, channel_set=None, n_records=None, dtype=None, + channels_indexes=None): """ reads stream of record bytes using dataRead module if available otherwise bitarray Parameters ------------ - bita : stream + bit_stream : stream stream of bytes info: info class - channelSet : set of str, optional + channel_set : set of str, optional set of channel to read - nrecords: int + n_records: int number of records dtype: numpy dtype channels_indexes: list of int @@ -951,16 +950,16 @@ def read_channels_from_bytes(self, bita, info, channelSet=None, nrecords=None, rec : numpy recarray contains a matrix of raw data in a recarray (attributes corresponding to channel name) """ - if nrecords is None: - nrecords = self.numberOfRecords + if n_records is None: + n_records = self.numberOfRecords # initialise recarray if dtype is None: - buf, channels_indexes = self.initialise_recarray(info, channelSet, nrecords, dtype, channels_indexes) + buf, channels_indexes = self.initialise_recarray(info, channel_set, n_records, dtype, channels_indexes) else: - buf = recarray(nrecords, dtype=dtype) + buf = recarray(n_records, dtype=dtype) if buf is not None: # at least some channels should be parsed if dataRead_available: # use rather cython compiled code for performance - bytesdata = bytes(bita) + bytesdata = bytes(bit_stream) for chan in channels_indexes: if self[chan].isCABlock(info): ca = self[chan].CABlock(info) @@ -971,27 +970,27 @@ def read_channels_from_bytes(self, bita, info, channelSet=None, nrecords=None, dataRead(bytesdata, self[chan].bitCount(info), self[chan].signalDataType(info), self[chan].nativedataFormat(info), - nrecords, self.CGrecordLength, + n_records, self.CGrecordLength, self[chan].bitOffset(info), self[chan].posByteBeg(info), self[chan].nBytes, array_flag) return buf else: - return self.read_channels_from_bytes_fallback(bita, info, channelSet, nrecords, dtype) + return self.read_channels_from_bytes_fallback(bit_stream, info, channel_set, n_records, dtype) else: return [] - def read_channels_from_bytes_fallback(self, bita, info, channel_set=None, nrecords=None, dtype=None, + def read_channels_from_bytes_fallback(self, bit_stream, info, channel_set=None, n_records=None, dtype=None, channels_indexes=None): """ reads stream of record bytes using bitarray in case no dataRead available Parameters ------------ - bita : stream + bit_stream : stream stream of bytes info: info class channel_set : set of str, optional set of channel to read - nrecords: int + n_records: int number of records dtype: numpy dtype channels_indexes: list of int @@ -1002,74 +1001,74 @@ def read_channels_from_bytes_fallback(self, bita, info, channel_set=None, nrecor contains a matrix of raw data in a recarray (attributes corresponding to channel name) """ - def signedInt(temp, extension): + def signed_int(temp, extension): """ extend bits of signed data managing two's complement """ extension.setall(False) - extensionInv = bitarray(extension, endian='little') - extensionInv.setall(True) - for i in range(nrecords): # extend data of bytes to match numpy requirement - signBit = temp[i][-1] - if not signBit: # positive value, extend with 0 + extension_inv = bitarray(extension, endian='little') + extension_inv.setall(True) + for i in range(n_records): # extend data of bytes to match numpy requirement + sign_bit = temp[i][-1] + if not sign_bit: # positive value, extend with 0 temp[i].extend(extension) else: # negative value, extend with 1 - signBit = temp[i].pop(-1) - temp[i].extend(extensionInv) - temp[i].append(signBit) + sign_bit = temp[i].pop(-1) + temp[i].extend(extension_inv) + temp[i].append(sign_bit) return temp - if nrecords is None: - nrecords = self.numberOfRecords + if n_records is None: + n_records = self.numberOfRecords if dtype is None: - buf, channels_indexes = self.initialise_recarray(info, channel_set, nrecords, dtype, channels_indexes) + buf, channels_indexes = self.initialise_recarray(info, channel_set, n_records, dtype, channels_indexes) else: - buf = recarray(nrecords, dtype=dtype) + buf = recarray(n_records, dtype=dtype) if buf is not None: # read data from bitarray import bitarray B = bitarray(endian="little") # little endian by default - B.frombytes(bytes(bita)) + B.frombytes(bytes(bit_stream)) record_bit_size = self.CGrecordLength * 8 for chan in channels_indexes: - signalDataType = self[chan].signalDataType(info) - nBytes = self[chan].nBytes + signal_data_type = self[chan].signalDataType(info) + n_bytes = self[chan].nBytes if not self[chan].type in (1, 2): temp = [B[self[chan].posBitBeg(info) + record_bit_size * i: self[chan].posBitEnd(info) + record_bit_size * i] - for i in range(nrecords)] + for i in range(n_records)] nbytes = len(temp[0].tobytes()) - if not nbytes == nBytes and \ - signalDataType not in (6, 7, 8, 9, 10, 11, 12): # not Ctype byte length - byte = bitarray(8 * (nBytes - nbytes), endian='little') + if not nbytes == n_bytes and \ + signal_data_type not in (6, 7, 8, 9, 10, 11, 12): # not Ctype byte length + byte = bitarray(8 * (n_bytes - nbytes), endian='little') byte.setall(False) - if signalDataType not in (2, 3): # not signed integer - for i in range(nrecords): # extend data of bytes to match numpy requirement + if signal_data_type not in (2, 3): # not signed integer + for i in range(n_records): # extend data of bytes to match numpy requirement temp[i].extend(byte) else: # signed integer (two's complement), keep sign bit and extend with bytes - temp = signedInt(temp, byte) - nTrailBits = nBytes*8 - self[chan].bitCount(info) - if signalDataType in (2, 3) and \ - nbytes == nBytes and \ - nTrailBits > 0: # Ctype byte length but signed integer - trailBits = bitarray(nTrailBits, endian='little') - temp = signedInt(temp, trailBits) + temp = signed_int(temp, byte) + n_trail_bits = n_bytes*8 - self[chan].bitCount(info) + if signal_data_type in (2, 3) and \ + nbytes == n_bytes and \ + n_trail_bits > 0: # Ctype byte length but signed integer + trail_bits = bitarray(n_trail_bits, endian='little') + temp = signed_int(temp, trail_bits) else: # Channel Array temp = [B[self[chan].posBitBeg(info) + record_bit_size * i: - self[chan].posBitBeg(info) + 8 * nBytes + record_bit_size * i] - for i in range(nrecords)] + self[chan].posBitBeg(info) + 8 * n_bytes + record_bit_size * i] + for i in range(n_records)] if 's' not in self[chan].Format(info): CFormat = self[chan].CFormat(info) if ('>' in self[chan].dataFormat(info) and byteorder == 'little') or \ (byteorder == 'big' and '<' in self[chan].dataFormat(info)): temp = [CFormat.unpack(temp[i].tobytes())[0] - for i in range(nrecords)] + for i in range(n_records)] temp = asarray(temp).byteswap().newbyteorder() else: temp = [CFormat.unpack(temp[i].tobytes())[0] - for i in range(nrecords)] + for i in range(n_records)] temp = asarray(temp) else: temp = [temp[i].tobytes() - for i in range(nrecords)] + for i in range(n_records)] temp = asarray(temp) buf[self[chan].name] = temp return buf @@ -1120,7 +1119,7 @@ class Mdf4(MdfSkeleton): returns a list of tuples """ - def read4(self, file_name=None, info=None, multiProc=False, channel_list=None, convert_after_read=True, + def read4(self, file_name=None, info=None, multi_processed=False, channel_list=None, convert_after_read=True, compression=False, metadata=2): """ Reads mdf 4.x file data and stores it in dict @@ -1132,7 +1131,7 @@ def read4(self, file_name=None, info=None, multiProc=False, channel_list=None, c info : mdfinfo4.info4 class info4 class containing all MDF Blocks - multiProc : bool + multi_processed : bool flag to activate multiprocessing of channel data conversion channel_list : list of str, optional @@ -1158,7 +1157,7 @@ def read4(self, file_name=None, info=None, multiProc=False, channel_list=None, c """ - self.multiProc = multiProc + self.multiProc = multi_processed if self.fileName is None and info is not None: self.fileName = info.fileName @@ -1186,9 +1185,9 @@ def read4(self, file_name=None, info=None, multiProc=False, channel_list=None, c # reads metadata if not self._noDataLoading: - fileDateTime = gmtime(info['HD']['hd_start_time_ns'] / 1000000000) - ddate = strftime('%Y-%m-%d', fileDateTime) - ttime = strftime('%H:%M:%S', fileDateTime) + file_date_time = gmtime(info['HD']['hd_start_time_ns'] / 1000000000) + ddate = strftime('%Y-%m-%d', file_date_time) + ttime = strftime('%H:%M:%S', file_date_time) def returnField(obj, field): try: @@ -1213,41 +1212,41 @@ def returnField(obj, field): data_groups = [self[channel][idField][0] for channel in channel_list] for dataGroup in data_groups: - channelSet = channel_set_file + channel_set = channel_set_file if not info['DG'][dataGroup]['dg_data'] == 0 and \ - (channelSet is None or - len(channelSet & info['ChannelNamesByDG'][dataGroup]) > 0): # there is data block and channel in + (channel_set is None or + len(channel_set & info['ChannelNamesByDG'][dataGroup]) > 0): # there is data block and channel in if minimal > 1 and not self._noDataLoading: # load CG, CN and CC block info - info.read_CGBlock(info.fid, dataGroup, channelSet, minimal=minimal) + info.read_cg_block(info.fid, dataGroup, channel_set, minimal=minimal) if info['CG'][dataGroup][0]['cg_cycle_count']: # data exists # Pointer to data block - pointerToData = info['DG'][dataGroup]['dg_data'] + pointer_to_data = info['DG'][dataGroup]['dg_data'] if 'dataClass' not in info['DG'][dataGroup]: - buf = Data(info.fid, pointerToData) + buf = Data(info.fid, pointer_to_data) for channelGroup in info['CG'][dataGroup]: temp = Record(dataGroup, channelGroup) # create record class temp.load_info(info) # load all info related to record buf.add_record(temp) # adds record to DATA - recordID = info['CG'][dataGroup][channelGroup]['cg_record_id'] + record_id = info['CG'][dataGroup][channelGroup]['cg_record_id'] if temp.master['name'] is not None \ - and buf[recordID]['record'].channelNames: - if channelSet is not None and not self._noDataLoading\ - and temp.master['name'] not in channelSet: - channelSet.add(temp.master['name']) # adds master channel in channelSet if missing - if channelSet is not None and buf[recordID]['record'].CANOpen: + and buf[record_id]['record'].channelNames: + if channel_set is not None and not self._noDataLoading\ + and temp.master['name'] not in channel_set: + channel_set.add(temp.master['name']) # adds master channel in channelSet if missing + if channel_set is not None and buf[record_id]['record'].CANOpen: # adds CANOpen channels if existing in not empty channelSet - if buf[recordID]['record'].CANOpen == 'time': - channelSet.update(('ms', 'days')) - elif buf[recordID]['record'].CANOpen == 'date': - channelSet.update(('ms', 'minute', 'hour', 'day', 'month', 'year')) + if buf[record_id]['record'].CANOpen == 'time': + channel_set.update(('ms', 'days')) + elif buf[record_id]['record'].CANOpen == 'date': + channel_set.update(('ms', 'minute', 'hour', 'day', 'month', 'year')) if self._noDataLoading: self.info['DG'][dataGroup]['dataClass'] = buf else: buf = self.info['DG'][dataGroup]['dataClass'] # reads raw data from data block with DATA and _data_block classes - buf.read(channelSet, info, self.fileName) + buf.read(channel_set, info, self.fileName) channel_groups = buf if self._noDataLoading and channel_list is not None: @@ -1255,56 +1254,56 @@ def returnField(obj, field): for channel in channel_list] # processing data from buf then transfer to self - for recordID in channel_groups: # for each channel group in data block - if 'record' in buf[recordID]: - master_channel = buf[recordID]['record'].master['name'] + for record_id in channel_groups: # for each channel group in data block + if 'record' in buf[record_id]: + master_channel = buf[record_id]['record'].master['name'] - channels = buf[recordID]['record'] + channels = buf[record_id]['record'] if self._noDataLoading and channel_list is not None: channels = [channels[self[channel][idField][2]] for channel in channel_list] for chan in channels: # for each channel class - if channelSet is None or chan.name in channelSet: + if channel_set is None or chan.name in channel_set: if not chan.type == 4: # normal channel - if chan.channelType(info) not in (3, 6): # not virtual channel + if chan.channel_type(info) not in (3, 6): # not virtual channel # in case record is used for several channels - if channelSet is None and not buf[recordID]['record'].hiddenBytes \ - and buf[recordID]['record'].byte_aligned: - recordName = buf[recordID]['record'].recordToChannelMatching[chan.name] + if channel_set is None and not buf[record_id]['record'].hiddenBytes \ + and buf[record_id]['record'].byte_aligned: + record_name = buf[record_id]['record'].recordToChannelMatching[chan.name] else: - recordName = chan.name - if 'data' in buf[recordID] and \ - buf[recordID]['data'] is not None: # no data in channel group - temp = buf[recordID]['data'][recordName] # extract channel vector + record_name = chan.name + if 'data' in buf[record_id] and \ + buf[record_id]['data'] is not None: # no data in channel group + temp = buf[record_id]['data'][record_name] # extract channel vector else: temp = None else: # virtual channel - temp = arange(buf[recordID]['record'].numberOfRecords) + temp = arange(buf[record_id]['record'].numberOfRecords) # Process concatenated bits inside uint8 - bitCount = chan.bitCount(info) - if buf[recordID]['record'].byte_aligned \ - and not buf[recordID]['record'].hiddenBytes and \ - channelSet is None and\ - 0 < bitCount < 64 and bitCount not in (8, 16, 32) \ + bit_count = chan.bit_count(info) + if buf[record_id]['record'].byte_aligned \ + and not buf[record_id]['record'].hiddenBytes and \ + channel_set is None and\ + 0 < bit_count < 64 and bit_count not in (8, 16, 32) \ and temp is not None\ and temp.dtype.kind not in ('S', 'U'): # if channel data do not use complete bytes and Ctypes - signal_data_type = chan.signalDataType(info) + signal_data_type = chan.signal_data_type(info) if signal_data_type in (0, 1, 2, 3): # integers - bitOffset = chan.bitOffset(info) - if bitOffset > 0: - temp = right_shift(temp, bitOffset) - mask = int(pow(2, bitCount) - 1) # masks isBitUnit8 + bit_offset = chan.bit_offset(info) + if bit_offset > 0: + temp = right_shift(temp, bit_offset) + mask = int(pow(2, bit_count) - 1) # masks isBitUnit8 temp = bitwise_and(temp, mask) if signal_data_type in (2, 3): # signed integer, moving bit sign of two's complement - signBitMask = (1 << (bitCount - 1)) - signExtend = ((1 << (temp.itemsize * 8 - bitCount)) - 1) << bitCount - signBit = bitwise_and(temp, signBitMask) - for number, sign in enumerate(signBit): + sign_bit_mask = (1 << (bit_count - 1)) + sign_extend = ((1 << (temp.itemsize * 8 - bit_count)) - 1) << bit_count + sign_bit = bitwise_and(temp, sign_bit_mask) + for number, sign in enumerate(sign_bit): # negative value, sign extend if sign: - temp[number] |= signExtend + temp[number] |= sign_extend else: # should not happen warn('bit count and offset not applied to correct ' 'data type {}'.format(chan.name)) @@ -1314,14 +1313,14 @@ def returnField(obj, field): if temp is not None: # channel contains data # string data decoding if temp.dtype.kind == 'S': - signalDataType = chan.signalDataType(info) - if signalDataType == 6: # string ISO-8859-1 Latin + signal_data_type = chan.signal_data_type(info) + if signal_data_type == 6: # string ISO-8859-1 Latin encoding = 'latin-1' - elif signalDataType == 7: # UTF-8 + elif signal_data_type == 7: # UTF-8 encoding = 'UTF-8' - elif signalDataType == 8: + elif signal_data_type == 8: encoding = 'UTF-16LE' - elif signalDataType == 9: # UTF-16 big endian + elif signal_data_type == 9: # UTF-16 big endian encoding = 'UTF-16BE' else: encoding = None @@ -1337,14 +1336,14 @@ def returnField(obj, field): # channel creation self.add_channel(chan.name, temp, master_channel, - master_type=chan.channelSyncType(info), + master_type=chan.channel_sync_type(info), unit=chan.unit(info), description=chan.desc(info), - conversion=chan.conversion(info), info=chan.CNBlock(info), + conversion=chan.conversion(info), info=chan.cn_block(info), compression=compression, identifier=info.unique_id(chan.dataGroup, chan.channelGroup, chan.channelNumber)) - if chan.channelType(info) == 4: # sync channel + if chan.channel_type(info) == 4: # sync channel # attach stream to be synchronised self.set_channel_attachment(chan.name, chan.attachment(info.fid, info)) if chan.has_invalid_bit(info): # has invalid bit @@ -1352,17 +1351,17 @@ def returnField(obj, field): self.set_invalid_channel(chan.name, 'invalid_bytes{}'.format(dataGroup)) else: # invalid bytes channel - data = buf[recordID]['data'].__getattribute__(chan.name) + data = buf[record_id]['data'].__getattribute__(chan.name) data = frombuffer(data.tobytes(), dtype='u1').reshape(len(data), data.dtype.itemsize) self.add_channel(chan.name, data, master_channel, master_type=0, unit='', description='', info=None, compression=compression, identifier=None) - buf[recordID].pop('data', None) + buf[record_id].pop('data', None) del buf if minimal > 1: # clean CN, CC and CG info to free memory - info.cleanDGinfo(dataGroup) + info.clean_dg_info(dataGroup) info.fid.close() # close file if convert_after_read and not compression: @@ -1396,15 +1395,14 @@ def _get_channel_data_4(self, channel_name, raw_data=False): (self.info.fid, self.info.fileName, self.info.zipfile) = _open_mdf(self.fileName) self.read4(file_name=None, info=None, channel_list=[channel_name], convert_after_read=False) if not raw_data: - return self._convert_channel_data_4(self.get_channel(channel_name), channel_name, - self.convert_tables)[channel_name] + return self._convert_channel_data_4(self.get_channel(channel_name), channel_name, self.convert_tables)[channel_name] else: return self.get_channel(channel_name)[dataField] else: return None @staticmethod - def _convert_channel_data_4(channel, channel_name, convert_tables, multiProc=False, Q=None): + def _convert_channel_data_4(channel, channel_name, convert_tables, multi_processed=False, q=None): """converts specific channel from raw to physical data according to CCBlock information Parameters @@ -1415,9 +1413,9 @@ def _convert_channel_data_4(channel, channel_name, convert_tables, multiProc=Fal name of channel convert_tables : bool activates computation intensive loops for conversion with tables. Default is False - multiProc : bool, default False + multi_processed : bool, default False flag to put data in multiprocess queue - Q : Queue class, default None + q : Queue class, default None Queue used for multiprocessing Returns @@ -1427,41 +1425,41 @@ def _convert_channel_data_4(channel, channel_name, convert_tables, multiProc=Fal conversion type """ if channel[dataField] is None: - vect = channel[dataField] + vector = channel[dataField] else: if isinstance(channel[dataField], CompressedData): - vect = channel[dataField].decompression() # uncompressed blosc data + vector = channel[dataField].decompression() # uncompressed blosc data else: - vect = channel[dataField][:] # to have bcolz uncompressed data + vector = channel[dataField][:] # to have bcolz uncompressed data if conversionField in channel and channel[conversionField]['type']: # there is conversion property - text_type = vect.dtype.kind in ['S', 'U', 'V'] # channel of string or not ? + text_type = vector.dtype.kind in ['S', 'U', 'V'] # channel of string or not ? conversion_type = channel[conversionField]['type'] conversion_parameter = channel[conversionField]['parameters'] if conversion_type == 1 and not text_type: - vect = _linear_conversion(vect, conversion_parameter['cc_val']) + vector = _linear_conversion(vector, conversion_parameter['cc_val']) elif conversion_type == 2 and not text_type: - vect = _rational_conversion(vect, conversion_parameter['cc_val']) + vector = _rational_conversion(vector, conversion_parameter['cc_val']) elif conversion_type == 3 and not text_type: - vect = _formula_conversion(vect, conversion_parameter['cc_ref']['Comment']) + vector = _formula_conversion(vector, conversion_parameter['cc_ref']['Comment']) elif conversion_type == 4 and not text_type: - vect = _value_to_value_table_with_interpolation_conversion(vect, conversion_parameter['cc_val']) + vector = _value_to_value_table_with_interpolation_conversion(vector, conversion_parameter['cc_val']) elif conversion_type == 5 and not text_type: - vect = _value_to_value_table_without_interpolation_conversion(vect, conversion_parameter['cc_val']) + vector = _value_to_value_table_without_interpolation_conversion(vector, conversion_parameter['cc_val']) elif conversion_type == 6 and not text_type and convert_tables: - vect = _value_range_to_value_table_conversion(vect, conversion_parameter['cc_val']) + vector = _value_range_to_value_table_conversion(vector, conversion_parameter['cc_val']) elif conversion_type == 7 and not text_type and convert_tables: - vect = _value_to_text_conversion(vect, conversion_parameter['cc_val'], conversion_parameter['cc_ref']) + vector = _value_to_text_conversion(vector, conversion_parameter['cc_val'], conversion_parameter['cc_ref']) elif conversion_type == 8 and not text_type and convert_tables: - vect = _value_range_to_text_conversion(vect, conversion_parameter['cc_val'], - conversion_parameter['cc_ref']) + vector = _value_range_to_text_conversion(vector, conversion_parameter['cc_val'], + conversion_parameter['cc_ref']) elif conversion_type == 9 and text_type and convert_tables: - vect = _text_to_value_conversion(vect, conversion_parameter['cc_val'], conversion_parameter['cc_ref']) + vector = _text_to_value_conversion(vector, conversion_parameter['cc_val'], conversion_parameter['cc_ref']) elif conversion_type == 10 and text_type and convert_tables: - vect = _text_to_text_conversion(vect, conversion_parameter['cc_ref']) + vector = _text_to_text_conversion(vector, conversion_parameter['cc_ref']) L = dict() - L[channel_name] = vect - if multiProc: - Q.put(L) + L[channel_name] = vector + if multi_processed: + q.put(L) else: return L @@ -1528,10 +1526,10 @@ def write4(self, file_name=None, compression=False): # Starts first to write ID and header if file_name is None: - splitName = splitext(self.fileName) - if splitName[-1] in ('.mfxz', '.MFXZ'): - splitName[-1] = '.mfx' # do not resave in compressed file - file_name = ''.join([splitName[-2], '_New', splitName[-1]]) + split_name = splitext(self.fileName) + if split_name[-1] in ('.mfxz', '.MFXZ'): + split_name[-1] = '.mfx' # do not resave in compressed file + file_name = ''.join([split_name[-2], '_New', split_name[-1]]) fid = open(file_name, 'wb') # buffering should automatically be set # IDBLock writing temp = IDBlock() @@ -1573,10 +1571,10 @@ def write4(self, file_name=None, compression=False): if self.masterChannelList: # some channels exist for dataGroup, masterChannel in enumerate(self.masterChannelList): # writes dataGroup Block - DG = DGBlock() - DG['block_start'] = pointer - pointer = DG['block_start'] + 64 - DG['CG'] = pointer # First CG link + dg = DGBlock() + dg['block_start'] = pointer + pointer = dg['block_start'] + 64 + dg['CG'] = pointer # First CG link blocks = OrderedDict() # initialise blocks for this datagroup # write CGBlock @@ -1592,28 +1590,28 @@ def write4(self, file_name=None, compression=False): cg_cycle_count = 1 elif master_channel_data not in self.masterChannelList[masterChannel]: cg_cycle_count = len(self._get_channel_data_4(self.masterChannelList[masterChannel][0])) - warn('no master channel in datagroup {}'.format(dataGroup)) + warn('no master channel in data group {}'.format(dataGroup)) else: - # no data in datagroup, skip - warn('no data in datagroup {0} with master channel {1}'.format(dataGroup, masterChannel)) + # no data in data group, skip + warn('no data in data group {0} with master channel {1}'.format(dataGroup, masterChannel)) continue blocks['CG']['cg_cycle_count'] = cg_cycle_count # write channels record_byte_offset = 0 - CN_flag = 0 + cn_flag = 0 number_of_channel = 0 - nRecords = 0 - dataList = () + n_records = 0 + data_list = () last_channel = 0 - for nchannel, channel in enumerate(self.masterChannelList[masterChannel]): + for n_channel, channel in enumerate(self.masterChannelList[masterChannel]): data = self.getChannelData(channel) # no interest to write invalid bytes as channel, should be processed if needed before writing if channel.find('invalid_bytes') == -1 and data is not None and len(data) > 0: - last_channel = nchannel + last_channel = n_channel data_ndim = data.ndim - 1 if not data_ndim: - dataList = dataList + (data, ) + data_list = data_list + (data, ) else: # data contains arrays data_dim_size = data.shape if not cg_cycle_count == data_dim_size[0]: @@ -1626,24 +1624,24 @@ def write4(self, file_name=None, compression=False): PNd *= x flattened = reshape(data, (cg_cycle_count, PNd)) for i in range(PNd): - dataList = dataList + (flattened[:, i],) + data_list = data_list + (flattened[:, i],) number_of_channel += 1 - blocks[nchannel] = CNBlock() + blocks[n_channel] = CNBlock() if issubdtype(data.dtype, numpy_number): # is numeric - blocks[nchannel]['cn_val_range_min'] = npmin(data) - blocks[nchannel]['cn_val_range_max'] = npmax(data) - blocks[nchannel]['cn_flags'] = 8 # only Bit 3: Limit range valid flag + blocks[n_channel]['cn_val_range_min'] = npmin(data) + blocks[n_channel]['cn_val_range_max'] = npmax(data) + blocks[n_channel]['cn_flags'] = 8 # only Bit 3: Limit range valid flag else: - blocks[nchannel]['cn_val_range_min'] = 0 - blocks[nchannel]['cn_val_range_max'] = 0 - blocks[nchannel]['cn_flags'] = 0 + blocks[n_channel]['cn_val_range_min'] = 0 + blocks[n_channel]['cn_val_range_max'] = 0 + blocks[n_channel]['cn_flags'] = 0 if masterChannel is not channel: - blocks[nchannel]['cn_type'] = 0 - blocks[nchannel]['cn_sync_type'] = 0 + blocks[n_channel]['cn_type'] = 0 + blocks[n_channel]['cn_sync_type'] = 0 else: - blocks[nchannel]['cn_type'] = 2 # master channel - blocks[nchannel]['cn_sync_type'] = 1 # default is time channel - nRecords = len(data) + blocks[n_channel]['cn_type'] = 2 # master channel + blocks[n_channel]['cn_sync_type'] = 1 # default is time channel + n_records = len(data) cn_numpy_kind = data.dtype.kind if cn_numpy_kind in ('u', 'b'): @@ -1661,20 +1659,20 @@ def write4(self, file_name=None, compression=False): else: warn('{} {} {}'.format(channel, data.dtype, cn_numpy_kind)) raise Exception('Not recognized dtype') - blocks[nchannel]['cn_data_type'] = data_type - blocks[nchannel]['cn_bit_offset'] = 0 # always byte aligned - blocks[nchannel]['cn_byte_offset'] = record_byte_offset + blocks[n_channel]['cn_data_type'] = data_type + blocks[n_channel]['cn_bit_offset'] = 0 # always byte aligned + blocks[n_channel]['cn_byte_offset'] = record_byte_offset byte_count = data.dtype.itemsize record_byte_offset += byte_count - blocks[nchannel]['cn_bit_count'] = byte_count * 8 - blocks[nchannel]['block_start'] = pointer - pointer = blocks[nchannel]['block_start'] + 160 + blocks[n_channel]['cn_bit_count'] = byte_count * 8 + blocks[n_channel]['block_start'] = pointer + pointer = blocks[n_channel]['block_start'] + 160 # arrays handling if not data_ndim: - blocks[nchannel]['Composition'] = 0 + blocks[n_channel]['Composition'] = 0 else: - blocks[nchannel]['Composition'] = pointer # pointer to CABlock + blocks[n_channel]['Composition'] = pointer # pointer to CABlock # creates CABlock ca = ''.join([channel, '_CA']) blocks[ca] = CABlock() @@ -1684,16 +1682,16 @@ def write4(self, file_name=None, compression=False): blocks[ca].load(data.itemsize) pointer = blocks[ca]['block_start'] + blocks[ca]['block_length'] - if CN_flag: + if cn_flag: # Next DG - blocks[nchannel-1]['CN'] = blocks[nchannel]['block_start'] - blocks[nchannel]['CN'] = 0 # initialise 'CN' key + blocks[n_channel-1]['CN'] = blocks[n_channel]['block_start'] + blocks[n_channel]['CN'] = 0 # initialise 'CN' key else: - CN_flag = blocks[nchannel]['block_start'] - blocks[nchannel]['CN'] = 0 # creates first CN link, null for the moment + cn_flag = blocks[n_channel]['block_start'] + blocks[n_channel]['CN'] = 0 # creates first CN link, null for the moment # write channel name - blocks[nchannel]['TX'] = pointer + blocks[n_channel]['TX'] = pointer blocks[channel] = CommentBlock() blocks[channel]['block_start'] = pointer blocks[channel].load(channel, 'TX') @@ -1702,63 +1700,63 @@ def write4(self, file_name=None, compression=False): # write channel unit unit = self.get_channel_unit(channel) if unit is not None and len(unit) > 0: - blocks[nchannel]['Unit'] = pointer - unit_name = '{}{}{}'.format(channel, '_U_', nchannel) + blocks[n_channel]['Unit'] = pointer + unit_name = '{}{}{}'.format(channel, '_U_', n_channel) blocks[unit_name] = CommentBlock() blocks[unit_name]['block_start'] = pointer blocks[unit_name].load(unit, 'TX') pointer = blocks[unit_name]['block_start'] + blocks[unit_name]['block_length'] else: - blocks[nchannel]['Unit'] = 0 + blocks[n_channel]['Unit'] = 0 # write channel description desc = self.get_channel_desc(channel) if desc is not None and len(desc) > 0: - blocks[nchannel]['Comment'] = pointer - desc_name = '{}{}{}'.format(channel, '_C_', nchannel) + blocks[n_channel]['Comment'] = pointer + desc_name = '{}{}{}'.format(channel, '_C_', n_channel) blocks[desc_name] = CommentBlock() blocks[desc_name]['block_start'] = pointer blocks[desc_name].load(desc, 'TX') pointer = blocks[desc_name]['block_start'] + blocks[desc_name]['block_length'] else: - blocks[nchannel]['Comment'] = 0 + blocks[n_channel]['Comment'] = 0 - if nRecords == 0 and masterChannel is not self.masterChannelList[masterChannel]: + if n_records == 0 and masterChannel is not self.masterChannelList[masterChannel]: # No master channel in channel group - nRecords = len(dataList[0]) + n_records = len(data_list[0]) if last_channel in blocks: blocks[last_channel]['CN'] = 0 # last CN link is null # writes size of record in CG blocks['CG']['cg_data_bytes'] = record_byte_offset - # data pointer in datagroup - DG['data'] = pointer + # data pointer in data group + dg['data'] = pointer if compression: data = HLBlock() - data.load(record_byte_offset, nRecords, pointer) - DG_start_position = fid.tell() - DG['DG'] = 0 + data.load(record_byte_offset, n_records, pointer) + dg_start_position = fid.tell() + dg['DG'] = 0 else: data = DTBlock() - data.load(record_byte_offset, nRecords, pointer) - DG['DG'] = data['end_position'] + data.load(record_byte_offset, n_records, pointer) + dg['DG'] = data['end_position'] - DG.write(fid) # write DG block + dg.write(fid) # write DG block # writes all blocks (CG, CN, TX for unit and description) before writing data block for block in blocks.values(): block.write(fid) # data block writing - pointer = data.write(fid, fromarrays(dataList).tobytes(order='F')) + pointer = data.write(fid, fromarrays(data_list).tobytes(order='F')) if compression: # next DG position is not predictable due to DZ Blocks unknown length - fid.seek(DG_start_position + 24) + fid.seek(dg_start_position + 24) fid.write(pack(' 0: # long name of signal - longSignalName = \ + long_signal_name = \ read_tx_block(fid, self['CNBlock'][dg][cg][channel]['pointerToASAMNameBlock']) - if len(longSignalName) > len(shortSignalName): # long name should be used - signalname = longSignalName + if len(long_signal_name) > len(short_signal_name): # long name should be used + signal_name = long_signal_name else: - signalname = shortSignalName + signal_name = short_signal_name else: - signalname = shortSignalName - signalname = signalname.split('\\') - if len(signalname) > 1: - self['CNBlock'][dg][cg][channel]['deviceName'] = signalname[1] - signalname = signalname[0] + signal_name = short_signal_name + signal_name = signal_name.split('\\') + if len(signal_name) > 1: + self['CNBlock'][dg][cg][channel]['deviceName'] = signal_name[1] + signal_name = signal_name[0] if self.filterChannelNames: - signalname = signalname.split('.')[-1] # filters channels modules + signal_name = signal_name.split('.')[-1] # filters channels modules - if signalname in self['ChannelNamesByDG'][dg]: # for unsorted data + if signal_name in self['ChannelNamesByDG'][dg]: # for unsorted data pointer = self['CNBlock'][dg][cg][channel]['pointerToCEBlock'] if pointer: temp = read_ce_block(fid, pointer) @@ -227,8 +225,8 @@ def readCGBlock(self, fid, dg, minimal=0): temp = dict() temp['tail'] = channel self['CNBlock'][dg][cg][channel]['signalName'] = \ - '{0}_{1}_{2}_{3}'.format(signalname, dg, cg, temp['tail']) - elif signalname in self['allChannelList']: + '{0}_{1}_{2}_{3}'.format(signal_name, dg, cg, temp['tail']) + elif signal_name in self['allChannelList']: # doublon name or master channel pointer = self['CNBlock'][dg][cg][channel]['pointerToCEBlock'] if pointer: @@ -236,13 +234,13 @@ def readCGBlock(self, fid, dg, minimal=0): else: temp = dict() temp['tail'] = dg - if '{0}_{1}'.format(signalname, temp['tail']) not in self['allChannelList']: - self['CNBlock'][dg][cg][channel]['signalName'] = '{0}_{1}'.format(signalname, temp['tail']) + if '{0}_{1}'.format(signal_name, temp['tail']) not in self['allChannelList']: + self['CNBlock'][dg][cg][channel]['signalName'] = '{0}_{1}'.format(signal_name, temp['tail']) else: - self['CNBlock'][dg][cg][channel]['signalName'] = '{0}_{1}_{2}'.format(signalname, + self['CNBlock'][dg][cg][channel]['signalName'] = '{0}_{1}_{2}'.format(signal_name, dg, temp['tail']) else: - self['CNBlock'][dg][cg][channel]['signalName'] = signalname + self['CNBlock'][dg][cg][channel]['signalName'] = signal_name self['ChannelNamesByDG'][dg].add(self['CNBlock'][dg][cg][channel]['signalName']) self['allChannelList'].add(self['CNBlock'][dg][cg][channel]['signalName']) @@ -268,25 +266,25 @@ def readCGBlock(self, fid, dg, minimal=0): # this reorder is meant to improve performance while parsing records using core.records.fromfile # as it will not use cn_byte_offset # first, calculate new mapping/order - nChannel = len(self['CNBlock'][dg][cg]) + n_channel = len(self['CNBlock'][dg][cg]) Map = zeros(shape=len(self['CNBlock'][dg][cg]), dtype=[('index', 'u4'), ('first_bit', 'u4')]) - for cn in range(nChannel): + for cn in range(n_channel): Map[cn] = (cn, self['CNBlock'][dg][cg][cn]['numberOfTheFirstBits']) - orderedMap = sort(Map, order='first_bit') + ordered_map = sort(Map, order='first_bit') - toChangeIndex = Map == orderedMap - for cn in range(nChannel): - if not toChangeIndex[cn]: + to_change_index = Map == ordered_map + for cn in range(n_channel): + if not to_change_index[cn]: # offset all indexes of indexes to be moved - self['CNBlock'][dg][cg][cn + nChannel] = self['CNBlock'][dg][cg].pop(cn) - self['CCBlock'][dg][cg][cn + nChannel] = self['CCBlock'][dg][cg].pop(cn) - for cn in range(nChannel): - if not toChangeIndex[cn]: + self['CNBlock'][dg][cg][cn + n_channel] = self['CNBlock'][dg][cg].pop(cn) + self['CCBlock'][dg][cg][cn + n_channel] = self['CCBlock'][dg][cg].pop(cn) + for cn in range(n_channel): + if not to_change_index[cn]: # change to ordered index - self['CNBlock'][dg][cg][cn] = self['CNBlock'][dg][cg].pop(orderedMap[cn][0] + nChannel) - self['CCBlock'][dg][cg][cn] = self['CCBlock'][dg][cg].pop(orderedMap[cn][0] + nChannel) + self['CNBlock'][dg][cg][cn] = self['CNBlock'][dg][cg].pop(ordered_map[cn][0] + n_channel) + self['CCBlock'][dg][cg][cn] = self['CCBlock'][dg][cg].pop(ordered_map[cn][0] + n_channel) - def cleanDGinfo(self, dg): + def clean_dg_info(self, dg): """ delete CN,CC and CG blocks related to data group Parameters @@ -307,12 +305,12 @@ def cleanDGinfo(self, dg): except KeyError: pass - def listChannels3(self, fileName=None, fid=None): + def list_channels3(self, file_name=None, fid=None): """ reads data, channel group and channel blocks to list channel names Attributes -------------- - fileName : str + file_name : str file name Returns @@ -320,74 +318,74 @@ def listChannels3(self, fileName=None, fid=None): list of channel names """ # Read MDF file and extract its complete structure - if fileName is not None: - self.fileName = fileName + if file_name is not None: + self.fileName = file_name # Open file - if fid is None and fileName is not None: + if fid is None and file_name is not None: fid = open(self.fileName, 'rb') - channelNameList = [] + channel_name_list = [] # Read header block (HDBlock) information # Set file pointer to start of HDBlock - HDpointer = 64 + hd_pointer = 64 # Read Header block info into structure - self['HDBlock'] = read_hd_block(fid, HDpointer) + self['HDBlock'] = read_hd_block(fid, hd_pointer) # Read Data Group blocks (DGBlock) information # Get pointer to first Data Group block - DGpointer = self['HDBlock']['pointerToFirstDGBlock'] + dg_pointer = self['HDBlock']['pointerToFirstDGBlock'] for dataGroup in range(self['HDBlock']['numberOfDataGroups']): # Read data Data Group block info into structure - self['DGBlock'][dataGroup] = read_dg_block(fid, DGpointer) + self['DGBlock'][dataGroup] = read_dg_block(fid, dg_pointer) # Get pointer to next Data Group block - DGpointer = self['DGBlock'][dataGroup]['pointerToNextDGBlock'] + dg_pointer = self['DGBlock'][dataGroup]['pointerToNextDGBlock'] # Read Channel Group block (CGBlock) information - offset set already # Read data Channel Group block info into structure - CGpointer = self['DGBlock'][dataGroup]['pointerToNextCGBlock'] + cg_pointer = self['DGBlock'][dataGroup]['pointerToNextCGBlock'] self['CGBlock'][dataGroup] = {} self['CNBlock'][dataGroup] = {} self['CCBlock'][dataGroup] = {} for channelGroup in range(self['DGBlock'][dataGroup]['numberOfChannelGroups']): self['CNBlock'][dataGroup][channelGroup] = {} self['CCBlock'][dataGroup][channelGroup] = {} - self['CGBlock'][dataGroup][channelGroup] = read_cg_block(fid, CGpointer) - CGpointer = self['CGBlock'][dataGroup][channelGroup]['pointerToNextCGBlock'] + self['CGBlock'][dataGroup][channelGroup] = read_cg_block(fid, cg_pointer) + cg_pointer = self['CGBlock'][dataGroup][channelGroup]['pointerToNextCGBlock'] # Get pointer to next first Channel block - CNpointer = self['CGBlock'][dataGroup][channelGroup]['pointerToFirstCNBlock'] + cn_pointer = self['CGBlock'][dataGroup][channelGroup]['pointerToFirstCNBlock'] - snames = set() + names_set = set() # For each Channel for channel in range(self['CGBlock'][dataGroup][channelGroup]['numberOfChannels']): # Read Channel block (CNBlock) information - #self.numberOfChannels += 1 + # self.numberOfChannels += 1 # Read data Channel block info into structure - self['CNBlock'][dataGroup][channelGroup][channel] = read_cn_block(fid, CNpointer) - CNpointer = self['CNBlock'][dataGroup][channelGroup][channel]['pointerToNextCNBlock'] + self['CNBlock'][dataGroup][channelGroup][channel] = read_cn_block(fid, cn_pointer) + cn_pointer = self['CNBlock'][dataGroup][channelGroup][channel]['pointerToNextCNBlock'] # Read Channel text blocks (TXBlock) # Clean signal name - shortSignalName = self['CNBlock'][dataGroup][channelGroup][channel]['signalName'] - CNTXpointer = self['CNBlock'][dataGroup][channelGroup][channel]['pointerToASAMNameBlock'] - if CNTXpointer > 0: - longSignalName = read_tx_block(fid, CNTXpointer) # long name of signal - if len(longSignalName) > len(shortSignalName): # long name should be used - signalname = longSignalName + short_signal_name = self['CNBlock'][dataGroup][channelGroup][channel]['signalName'] + cn_tx_pointer = self['CNBlock'][dataGroup][channelGroup][channel]['pointerToASAMNameBlock'] + if cn_tx_pointer > 0: + long_signal_name = read_tx_block(fid, cn_tx_pointer) # long name of signal + if len(long_signal_name) > len(short_signal_name): # long name should be used + signal_name = long_signal_name else: - signalname = shortSignalName + signal_name = short_signal_name else: - signalname = shortSignalName - signalname = signalname.split('\\') - signalname = signalname[0] + signal_name = short_signal_name + signal_name = signal_name.split('\\') + signal_name = signal_name[0] if self.filterChannelNames: - signalname = signalname.split('.')[-1] + signal_name = signal_name.split('.')[-1] - if signalname in snames: + if signal_name in names_set: pointer = self['CNBlock'][dataGroup][channelGroup][channel]['pointerToCEBlock'] if pointer: temp = read_ce_block(fid, pointer) @@ -395,18 +393,18 @@ def listChannels3(self, fileName=None, fid=None): temp = dict() temp['tail'] = channel self['CNBlock'][dataGroup][channelGroup][channel]['signalName'] = \ - '{0}_{1}'.format(signalname, temp['tail']) + '{0}_{1}'.format(signal_name, temp['tail']) warn('WARNING added number to duplicate signal name: {}'. format(self['CNBlock'][dataGroup][channelGroup][channel]['signalName'])) else: - self['CNBlock'][dataGroup][channelGroup][channel]['signalName'] = signalname - snames.add(signalname) + self['CNBlock'][dataGroup][channelGroup][channel]['signalName'] = signal_name + names_set.add(signal_name) - channelNameList.append(signalname) + channel_name_list.append(signal_name) # CLose the file fid.close() - return channelNameList + return channel_name_list def read_hd_block(fid, pointer, version=0): @@ -646,7 +644,7 @@ def read_ce_block(fid, pointer): return temp -def _generateDummyMDF3(info, channelList): +def _generate_dummy_mdf3(info, channel_list): """ computes MasterChannelList and mdf dummy dict from an info object Parameters @@ -654,52 +652,52 @@ def _generateDummyMDF3(info, channelList): info : info object information structure of file - channelList : list of str + channel_list : list of str list of channel names Returns ----------- a dict which keys are master channels in files with values a list of related channels of the raster """ - MasterChannelList = {} - allChannelList = set() - mdfdict = {} + master_channel_list = {} + all_channel_list = set() + mdf_dict = {} for dg in info['DGBlock']: master = '' - mastertype = 0 - ChannelNamesByDG =set() + master_type = 0 + channel_names_by_dg = set() for cg in info['CGBlock'][dg]: - channelNameList = [] + channel_name_list = [] for cn in info['CNBlock'][dg][cg]: name = info['CNBlock'][dg][cg][cn]['signalName'] - if name in ChannelNamesByDG: + if name in channel_names_by_dg: name = '{0}_{1}_{2}_{3}'.format(name, dg, cg, cn) - elif name in allChannelList: + elif name in all_channel_list: name = ''.join([name, '_{}'.format(dg)]) - if channelList is None or name in channelList: - channelNameList.append(name) - allChannelList.add(name) - ChannelNamesByDG.add(name) + if channel_list is None or name in channel_list: + channel_name_list.append(name) + all_channel_list.add(name) + channel_names_by_dg.add(name) # create mdf channel - mdfdict[name] = {} - mdfdict[name][dataField] = None + mdf_dict[name] = {} + mdf_dict[name][dataField] = None if 'signalDescription' in info['CNBlock'][dg][cg][cn]: - mdfdict[name][descriptionField] = \ + mdf_dict[name][descriptionField] = \ info['CNBlock'][dg][cg][cn]['signalDescription'] else: - mdfdict[name][descriptionField] = '' + mdf_dict[name][descriptionField] = '' if 'physicalUnit' in info['CCBlock'][dg][cg][cn]: - mdfdict[name][unitField] = info['CCBlock'][dg][cg][cn]['physicalUnit'] + mdf_dict[name][unitField] = info['CCBlock'][dg][cg][cn]['physicalUnit'] else: - mdfdict[name][unitField] = '' - mdfdict[name][masterField] = 0 # default is time - mdfdict[name][masterTypeField] = None - mdfdict[name][idField] = (dg, cg, cn) + mdf_dict[name][unitField] = '' + mdf_dict[name][masterField] = 0 # default is time + mdf_dict[name][masterTypeField] = None + mdf_dict[name][idField] = (dg, cg, cn) if info['CNBlock'][dg][cg][cn]['channelType']: # master channel of cg master = name - mastertype = info['CNBlock'][dg][cg][cn]['channelType'] - for chan in channelNameList: - mdfdict[chan][masterField] = master - mdfdict[chan][masterTypeField] = mastertype - MasterChannelList[master] = channelNameList - return (MasterChannelList, mdfdict) + master_type = info['CNBlock'][dg][cg][cn]['channelType'] + for chan in channel_name_list: + mdf_dict[chan][masterField] = master + mdf_dict[chan][masterTypeField] = master_type + master_channel_list[master] = channel_name_list + return (master_channel_list, mdf_dict) diff --git a/mdfreader/mdfinfo4.py b/mdfreader/mdfinfo4.py index 7975055..4b7c82d 100644 --- a/mdfreader/mdfinfo4.py +++ b/mdfreader/mdfinfo4.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -""" Measured Data Format blocks paser for version 4.x +""" Measured Data Format blocks parser for version 4.x Created on Sun Dec 15 12:57:28 2013 @@ -209,7 +209,8 @@ def read(self, fid): warn('Update of offset values for VLSD channel required ' 'in case a VLSD CG block is used') - def write(self, fid): + @staticmethod + def write(fid): """ Writes IDBlock """ # MDF versionTxt tool reserved version_int @@ -251,7 +252,7 @@ def read(self, fid=None): if self['hd_md_comment']: # if comments exist self['Comment'] = {} comment = CommentBlock() - comment.readCM(fid=fid, pointer=self['hd_md_comment'], MDType=3) + comment.read_cm(fid=fid, pointer=self['hd_md_comment'], MDType=3) self['Comment'].update(comment) def write(self, fid): @@ -298,7 +299,7 @@ def read(self, fid, pointer): if self['fh_md_comment']: # comments exist self['Comment'] = {} comment = CommentBlock() - comment.readCM(fid=fid, pointer=self['fh_md_comment'], MDType=4) + comment.read_cm(fid=fid, pointer=self['fh_md_comment'], MDType=4) self['Comment'].update(comment) def write(self, fid): @@ -339,12 +340,12 @@ def __init__(self, fid, pointer): if self['ch_md_comment']: # comments exist self['Comment'] = {} comment = CommentBlock() - comment.readCM(fid=fid, pointer=self['ch_md_comment']) + comment.read_cm(fid=fid, pointer=self['ch_md_comment']) self['Comment'].update(comment) if self['ch_tx_name']: # text block containing name of hierarchy level self['ch_name_level'] = {} comment = CommentBlock() - comment.readCM(fid=fid, pointer=self['ch_tx_name']) + comment.read_cm(fid=fid, pointer=self['ch_tx_name']) self['ch_name_level'].update(comment) @@ -352,7 +353,7 @@ class CommentBlock(dict): """ reads or writes Comment block and saves in class dict """ - def readCM(self, **kargs): + def read_cm(self, **kargs): """ reads Comment block and saves in class dict Parameters @@ -616,7 +617,7 @@ def read(self, fid, pointer): if self['dg_md_comment']: # comments exist self['Comment'] = {} comment = CommentBlock() - comment.readCM(fid=fid, pointer=self['dg_md_comment']) + comment.read_cm(fid=fid, pointer=self['dg_md_comment']) self['Comment'].update(comment) def write(self, fid): @@ -663,16 +664,16 @@ def read(self, fid, pointer): self['cg_invalid_bytes']) = _CGStruct.unpack(fid.read(104)) if self['cg_md_comment']: # comments exist self['Comment'] = CommentBlock() - self['Comment'].readCM(fid=fid, pointer=self['cg_md_comment']) + self['Comment'].read_cm(fid=fid, pointer=self['cg_md_comment']) if self['cg_tx_acq_name']: # comments exist self['acq_name'] = {} comment = CommentBlock() - comment.readCM(fid=fid, pointer=self['cg_tx_acq_name']) + comment.read_cm(fid=fid, pointer=self['cg_tx_acq_name']) self['acq_name'].update(comment) if self['cg_si_acq_source']: # comments exist self['acq_source'] = {} si = SIBlock() - si.readSI(fid=fid, pointer=self['cg_si_acq_source']) + si.read_si(fid=fid, pointer=self['cg_si_acq_source']) self['acq_source'].update(si) def write(self, fid): @@ -699,7 +700,7 @@ class CNBlock(dict): """ reads Channel block and saves in class dict """ - def read_CN(self, **kargs): + def read_cn(self, **kargs): if kargs['pointer'] != 0 and kargs['pointer'] is not None: kargs['fid'].seek(kargs['pointer']) (self['id'], @@ -753,10 +754,10 @@ def read_CN(self, **kargs): self['cn_default_x'] = None if self['cn_md_comment']: # comments exist self['Comment'] = CommentBlock() - self['Comment'].readCM(fid=kargs['fid'], pointer=self['cn_md_comment'], MDType=0, minimal=True) + self['Comment'].read_cm(fid=kargs['fid'], pointer=self['cn_md_comment'], MDType=0, minimal=True) if self['cn_md_unit']: # comments exist self['unit'] = CommentBlock() - self['unit'].readCM(fid=kargs['fid'], pointer=self['cn_md_unit'], MDType=1) + self['unit'].read_cm(fid=kargs['fid'], pointer=self['cn_md_unit'], MDType=1) if self['cn_sync_type'] and (self['unit'] is None or not self['unit']): # no units but already known by spec if self['cn_sync_type'] == 1: @@ -767,7 +768,7 @@ def read_CN(self, **kargs): self['unit'] = 'm' if self['cn_tx_name']: # comments exist comment = CommentBlock() - comment.readCM(fid=kargs['fid'], pointer=self['cn_tx_name'], MDType=0) + comment.read_cm(fid=kargs['fid'], pointer=self['cn_tx_name'], MDType=0) self['name'] = comment['name'] def write(self, fid): @@ -802,7 +803,7 @@ class CCBlock(dict): """ reads Channel Conversion block and saves in class dict """ - def readCC(self, fid, pointer): + def read_cc(self, fid, pointer): # block header if pointer != 0 and pointer is not None: fid.seek(pointer) @@ -831,7 +832,7 @@ def readCC(self, fid, pointer): pointer = self['cc_ref'] self['cc_ref'] = {} cc = CommentBlock() - cc.readCM(fid=fid, pointer=pointer) + cc.read_cm(fid=fid, pointer=pointer) self['cc_ref'].update(cc) elif self['cc_type']in (7, 8, 9, 10): # text list self['cc_ref'] = list(self['cc_ref']) @@ -842,22 +843,22 @@ def readCC(self, fid, pointer): # for algebraic formulae if identifier in ('##TX', '##MD', b'##TX', b'##MD'): temp = CommentBlock() - temp.readCM(fid=fid, pointer=self['cc_ref'][i]) + temp.read_cm(fid=fid, pointer=self['cc_ref'][i]) self['cc_ref'][i] = temp['Comment'] elif identifier in ('##CC', b'##CC'): # for table conversion # much more complicated nesting conversions !!! cc = CCBlock() - cc.readCC(fid, self['cc_ref'][i]) + cc.read_cc(fid, self['cc_ref'][i]) self['cc_ref'][i] = cc if self['cc_md_comment']: # comments exist self['Comment'] = CommentBlock() - self['Comment'].readCM(fid=fid, pointer=self['cc_md_comment'], MDType=6) + self['Comment'].read_cm(fid=fid, pointer=self['cc_md_comment'], MDType=6) if self['cc_md_unit']: # comments exist self['unit'] = CommentBlock() - self['unit'].readCM(fid=fid, pointer=self['cc_md_unit'], MDType=2) + self['unit'].read_cm(fid=fid, pointer=self['cc_md_unit'], MDType=2) if self['cc_tx_name']: # comments exist self['name'] = CommentBlock() - self['name'].readCM(fid=fid, pointer=self['cc_tx_name']) + self['name'].read_cm(fid=fid, pointer=self['cc_tx_name']) else: # no conversion self['cc_type'] = 0 @@ -969,7 +970,7 @@ def __init__(self, fid, pointer): if self['at_md_comment']: # comments exist self['Comment'] = {} comment = CommentBlock() - comment.readCM(fid=fid, pointer=self['at_md_comment']) + comment.read_cm(fid=fid, pointer=self['at_md_comment']) self['Comment'].update(comment) @@ -1020,10 +1021,10 @@ def __init__(self, fid, pointer): ATBlock(fid, self['ev_at_reference'][at]) if self['ev_md_comment']: # comments exist self['Comment'] = CommentBlock() - self['Comment'].readCM(fid=fid, pointer=self['ev_md_comment'], MDType=7) + self['Comment'].read_cm(fid=fid, pointer=self['ev_md_comment'], MDType=7) if self['ev_tx_name']: # comments exist self['name'] = CommentBlock() - self['name'].readCM(fid=fid, pointer=self['ev_tx_name']) + self['name'].read_cm(fid=fid, pointer=self['ev_tx_name']) class SRBlock(dict): @@ -1053,7 +1054,7 @@ class SIBlock(dict): """ reads Source Information block and saves in class dict """ - def readSI(self, fid, pointer): + def read_si(self, fid, pointer): # block header if pointer != 0 and pointer is not None: fid.seek(pointer) @@ -1078,11 +1079,11 @@ def readSI(self, fid, pointer): warn('unexpected SI bus type') # post treatment self['source_name'] = CommentBlock() - self['source_name'].readCM(fid=fid, pointer=self['si_tx_name']) + self['source_name'].read_cm(fid=fid, pointer=self['si_tx_name']) self['source_path'] = CommentBlock() - self['source_path'].readCM(fid=fid, pointer=self['si_tx_path']) + self['source_path'].read_cm(fid=fid, pointer=self['si_tx_path']) self['comment'] = CommentBlock() - self['comment'].readCM(fid=fid, pointer=self['si_md_comment'], MDType=5) + self['comment'].read_cm(fid=fid, pointer=self['si_md_comment'], MDType=5) class DTBlock(dict): @@ -1112,26 +1113,26 @@ def read(self, fid, link_count): (self['dl_flags'], dl_reserved, self['dl_count']) = unpack(' 1: - for counter in range(1, number_DL): - (nrecord_chunk, chunk_size) = chunks[counter] + number_dl = len(chunks) + self['block_length'] = 40 + 16 * number_dl + dl_offset = zeros(shape=number_dl, dtype=' 1: + for counter in range(1, number_dl): + (n_record_chunk, chunk_size) = chunks[counter] dl_offset[counter] = dl_offset[counter - 1] + chunk_size - data_bytes = (b'##DL', 0, self['block_length'], number_DL + 1, 0) - fid.write(pack('<4sI3Q'.format(number_DL, number_DL), *data_bytes)) - fid.write(pack('{0}Q'.format(number_DL), *zeros(shape=number_DL, dtype=' 0: - self['chunks'].append((nrecord_chunk, record_byte_offset * nrecord_chunk)) + n_chunks = (record_byte_offset * n_records) // chunk_size_writing + 1 + chunk_length = (record_byte_offset * n_records) // n_chunks + n_record_chunk = chunk_length // record_byte_offset + self['chunks'] = [(n_record_chunk, record_byte_offset * n_record_chunk)] * n_chunks + n_record_chunk = n_records - n_record_chunk * n_chunks + if n_record_chunk > 0: + self['chunks'].append((n_record_chunk, record_byte_offset * n_record_chunk)) def write(self, fid, data): fid.write(_HeaderStruct.pack(b'##HL', 0, self['block_length'], 1)) @@ -1240,7 +1241,7 @@ def write(self, fid, data): pointer += DL['block_length'] dl_data = zeros(shape=len(self['chunks']), dtype=' 1: for at in range(self['CN'][dg][cg][cn]['cn_attachment_count']): self['CN'][dg][cg][cn]['attachment'][at].update( - self.read_ATBlock(fid, self['CN'][dg][cg][cn]['cn_at_reference'][at])) + self.read_at_block(fid, self['CN'][dg][cg][cn]['cn_at_reference'][at])) elif self['CN'][dg][cg][cn]['cn_attachment_count'] == 1: self['CN'][dg][cg][cn]['attachment'][0].update( - self.read_ATBlock(fid, self['CN'][dg][cg][cn]['cn_at_reference'])) + self.read_at_block(fid, self['CN'][dg][cg][cn]['cn_at_reference'])) while self['CN'][dg][cg][cn]['cn_cn_next']: cn = cn + 1 self['CN'][dg][cg][cn] = {} temp = CNBlock() - temp.read_CN(fid=fid, pointer=self['CN'][dg][cg][cn - 1]['cn_cn_next']) + temp.read_cn(fid=fid, pointer=self['CN'][dg][cg][cn - 1]['cn_cn_next']) self['CN'][dg][cg][cn].update(temp) # check for MLSD if self['CN'][dg][cg][cn]['cn_type'] == 5: - MLSDChannels.append(cn) + mlsd_channels.append(cn) # reads Channel Conversion Block self['CC'][dg][cg][cn] = CCBlock() - self['CC'][dg][cg][cn].readCC(fid, self['CN'][dg][cg][cn]['cn_cc_conversion']) + self['CC'][dg][cg][cn].read_cc(fid, self['CN'][dg][cg][cn]['cn_cc_conversion']) if not channel_name_list: if not minimal: # reads Channel Source Information temp = SIBlock() - temp.readSI(fid, self['CN'][dg][cg][cn]['cn_si_source']) + temp.read_si(fid, self['CN'][dg][cg][cn]['cn_si_source']) if temp is not None: self['CN'][dg][cg][cn]['SI'] = dict() self['CN'][dg][cg][cn]['SI'].update(temp) @@ -1643,7 +1644,7 @@ def read_CNBlock(self, fid, dg, cg, channel_name_list=False, minimal=0): elif id in ('##CN', b'##CN'): self['CN'][dg][cg][cn]['CN'] = {} temp = CNBlock() - temp.read_CN(fid=fid, pointer=self['CN'][dg][cg][cn]['cn_composition']) + temp.read_cn(fid=fid, pointer=self['CN'][dg][cg][cn]['cn_composition']) self['CN'][dg][cg][cn]['CN'].update(temp) else: raise('unknown channel composition') @@ -1653,25 +1654,25 @@ def read_CNBlock(self, fid, dg, cg, channel_name_list=False, minimal=0): if self['CN'][dg][cg][cn]['cn_attachment_count'] > 1: for at in range(self['CN'][dg][cg][cn]['cn_attachment_count']): self['CN'][dg][cg][cn]['attachment'][at].update( - self.read_ATBlock(fid, self['CN'][dg][cg][cn]['cn_at_reference'][at])) + self.read_at_block(fid, self['CN'][dg][cg][cn]['cn_at_reference'][at])) elif self['CN'][dg][cg][cn]['cn_attachment_count'] == 1: self['CN'][dg][cg][cn]['attachment'][0].update( - self.read_ATBlock(fid, self['CN'][dg][cg][cn]['cn_at_reference'])) + self.read_at_block(fid, self['CN'][dg][cg][cn]['cn_at_reference'])) - MLSDChannels = self.read_composition(fid, dg, cg, MLSDChannels) + mlsd_channels = self.read_composition(fid, dg, cg, mlsd_channels) - if MLSDChannels: + if mlsd_channels: self['MLSD'] = {} self['MLSD'][dg] = {} self['MLSD'][dg][cg] = {} - for MLSDcn in MLSDChannels: + for MLSDcn in mlsd_channels: for cn in self['CN'][dg][cg]: if self['CN'][dg][cg][cn]['pointer'] == self['CN'][dg][cg][MLSDcn]['cn_data']: self['MLSD'][dg][cg][MLSDcn] = cn break return vlsd - def cleanDGinfo(self, dg): + def clean_dg_info(self, dg): """ delete CN,CC and CG blocks related to data group Parameters @@ -1696,7 +1697,7 @@ def cleanDGinfo(self, dg): except KeyError: pass - def read_composition(self, fid, dg, cg, MLSD_channels): + def read_composition(self, fid, dg, cg, mlsd_channels): """check for composition of channels, arrays or structures Parameters @@ -1707,7 +1708,7 @@ def read_composition(self, fid, dg, cg, MLSD_channels): data group number cg : int channel group number in data group - MLSD_channels : list of int + mlsd_channels : list of int channel numbers Returns @@ -1721,7 +1722,7 @@ def read_composition(self, fid, dg, cg, MLSD_channels): ID = unpack('4s', fid.read(4))[0] if ID in ('##CN', b'##CN'): # Structures self['CN'][dg][cg][chan] = CNBlock() - self['CN'][dg][cg][chan].read_CN(fid=fid, pointer=self['CN'][dg][cg][cn]['cn_composition']) + self['CN'][dg][cg][chan].read_cn(fid=fid, pointer=self['CN'][dg][cg][cn]['cn_composition']) # keep original non unique channel name self['CN'][dg][cg][chan]['orig_name'] = self['CN'][dg][cg][chan]['name'] # make sure channel name is unique @@ -1729,14 +1730,14 @@ def read_composition(self, fid, dg, cg, MLSD_channels): self._unique_channel_name(fid, self['CN'][dg][cg][chan]['name'], dg, cg, cn) self['CC'][dg][cg][chan] = CCBlock() - self['CC'][dg][cg][chan].readCC(fid, self['CN'][dg][cg][chan]['cn_cc_conversion']) + self['CC'][dg][cg][chan].read_cc(fid, self['CN'][dg][cg][chan]['cn_cc_conversion']) if self['CN'][dg][cg][chan]['cn_type'] == 5: - MLSD_channels.append(chan) + mlsd_channels.append(chan) while self['CN'][dg][cg][chan]['cn_cn_next']: chan += 1 self['CN'][dg][cg][chan] = CNBlock() - self['CN'][dg][cg][chan].read_CN(fid=fid, pointer=self['CN'][dg][cg][chan - 1]['cn_cn_next']) + self['CN'][dg][cg][chan].read_cn(fid=fid, pointer=self['CN'][dg][cg][chan - 1]['cn_cn_next']) # keep original non unique channel name self['CN'][dg][cg][chan]['orig_name'] = self['CN'][dg][cg][chan]['name'] # make sure channel name is unique @@ -1744,18 +1745,19 @@ def read_composition(self, fid, dg, cg, MLSD_channels): self._unique_channel_name(fid, self['CN'][dg][cg][chan]['name'], dg, cg, cn) self['CC'][dg][cg][chan] = CCBlock() - self['CC'][dg][cg][chan].readCC(fid, self['CN'][dg][cg][chan]['cn_cc_conversion']) + self['CC'][dg][cg][chan].read_cc(fid, self['CN'][dg][cg][chan]['cn_cc_conversion']) if self['CN'][dg][cg][chan]['cn_type'] == 5: - MLSD_channels.append(chan) + mlsd_channels.append(chan) # makes the channel virtual self['CN'][dg][cg][cn]['cn_type'] = 6 elif ID in ('##CA', b'##CA'): # arrays pass else: warn('unknown channel composition') - return MLSD_channels + return mlsd_channels - def read_SRBlock(self, fid, pointer): + @staticmethod + def read_sr_block(fid, pointer): """reads Sample Reduction Blocks Parameters @@ -1778,7 +1780,8 @@ def read_SRBlock(self, fid, pointer): sr_blocks[sr] = SRBlock(fid, sr_blocks[sr - 1]['sr_sr_next']) return sr_blocks - def read_ATBlock(self, fid, pointer): + @staticmethod + def read_at_block(fid, pointer): """reads Attachment blocks Parameters @@ -1828,7 +1831,7 @@ def list_channels_4(self, file_name=None, fid=None): # reads Data Group, channel groups and channel Blocks # recursively but not the other metadata block - self.read_DGBlock(fid, True) + self.read_dg_block(fid, True) for dg in self['DG']: for cg in self['CG'][dg]: @@ -1867,7 +1870,7 @@ def _unique_channel_name(self, fid, name, dg, cg, cn): if name in self['ChannelNamesByDG'][dg]: # for unsorted data if self['CN'][dg][cg][cn]['cn_si_source']: temp = SIBlock() - temp.readSI(fid, self['CN'][dg][cg][cn]['cn_si_source']) + temp.read_si(fid, self['CN'][dg][cg][cn]['cn_si_source']) if temp['si_tx_name'] > 0: source_name = temp['source_name']['Comment'] else: @@ -1878,7 +1881,7 @@ def _unique_channel_name(self, fid, name, dg, cg, cn): elif name in self['allChannelList']: # for sorted data if self['CN'][dg][cg][cn]['cn_si_source']: temp = SIBlock() - temp.readSI(fid, self['CN'][dg][cg][cn]['cn_si_source']) + temp.read_si(fid, self['CN'][dg][cg][cn]['cn_si_source']) if temp['si_tx_name'] > 0: source_name = temp['source_name']['Comment'] else: diff --git a/mdfreader/mdfreader.py b/mdfreader/mdfreader.py index 34052ac..7b34132 100644 --- a/mdfreader/mdfreader.py +++ b/mdfreader/mdfreader.py @@ -43,20 +43,20 @@ from warnings import warn from datetime import datetime from argparse import ArgumentParser -from numpy import arange, linspace, interp, all, diff, mean, vstack, hstack, float64, zeros, empty, delete +from numpy import arange, linspace, interp, all, diff, mean, vstack, hstack, float64, empty from numpy import nan, datetime64, array, searchsorted, clip from numpy.ma import MaskedArray -from .mdf3reader import mdf3 +from .mdf3reader import Mdf3 from .mdf4reader import Mdf4 from .mdf import _open_mdf, dataField, descriptionField, unitField, masterField, masterTypeField -from .mdfinfo3 import info3, _generateDummyMDF3 +from .mdfinfo3 import Info3, _generate_dummy_mdf3 from .mdfinfo4 import Info4, _generate_dummy_mdf4 PythonVersion = version_info PythonVersion = PythonVersion[0] -def _convertMatlabName(channel): +def _convert_to_matlab_name(channel): """Removes non allowed characters for a Matlab variable name Parameters @@ -74,32 +74,33 @@ def _convertMatlabName(channel): channel = channel.decode('utf-8') except: warn(u'channel name can not be decoded : {}'.format(channel)) - channelName = channel.replace('[', '_ls_') - channelName = channelName.replace(']', '_rs_') - channelName = channelName.replace('$', '') - channelName = channelName.replace('.', 'p') - channelName = channelName.replace('\\', '_bs_') - channelName = channelName.replace('/', '_fs_') - channelName = channelName.replace('(', '_lp_') - channelName = channelName.replace(')', '_rp_') - channelName = channelName.replace(',', '_c_') - channelName = channelName.replace('@', '_am_') - channelName = channelName.replace(' ', '_') - channelName = channelName.replace(':', '_co_') - channelName = channelName.replace('-', '_hy_') - channelName = channelName.replace('-', '_hy_') - def cleanName(name): - allowedStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.' + channel_name = channel.replace('[', '_ls_') + channel_name = channel_name.replace(']', '_rs_') + channel_name = channel_name.replace('$', '') + channel_name = channel_name.replace('.', 'p') + channel_name = channel_name.replace('\\', '_bs_') + channel_name = channel_name.replace('/', '_fs_') + channel_name = channel_name.replace('(', '_lp_') + channel_name = channel_name.replace(')', '_rp_') + channel_name = channel_name.replace(',', '_c_') + channel_name = channel_name.replace('@', '_am_') + channel_name = channel_name.replace(' ', '_') + channel_name = channel_name.replace(':', '_co_') + channel_name = channel_name.replace('-', '_hy_') + channel_name = channel_name.replace('-', '_hy_') + + def clean_name(name): + allowed_str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.' buf = '' for c in name: - if c in allowedStr: + if c in allowed_str: buf += c return buf - channelName = cleanName(channelName) - return channelName + channel_name = clean_name(channel_name) + return channel_name -class mdfinfo(dict): +class MdfInfo(dict): __slots__ = ['fileName', 'fid', 'zipfile', 'mdfversion', 'filterChannelNames'] """ MDFINFO is a class gathering information from block headers in a MDF (Measure Data Format) file Structure is nested dicts. Primary key is Block type, then data group, channel group and channel number. @@ -125,19 +126,19 @@ class mdfinfo(dict): Methods ------------ - readinfo( fileName = None, filterChannelNames=False ) + read_info( fileName = None, filterChannelNames=False ) Reads MDF file and extracts its complete structure - listChannels( fileName = None ) + list_channels( file_name = None ) Read MDF file blocks and returns a list of contained channels Examples -------------- >>> import mdfreader >>> FILENAME='toto.dat' - >>> yop=mdfreader.mdfinfo(FILENAME) + >>> yop=mdfreader.MdfInfo(FILENAME) or if you are just interested to have only list of channels - >>> yop=mdfreader.mdfinfo() # creates new instance of mdfinfo class - >>> yop.listChannels(FILENAME) # returns a simple list of channel names + >>> yop=mdfreader.MdfInfo() # creates new instance of mdfinfo class + >>> yop.list_channels(FILENAME) # returns a simple list of channel names """ def __init__(self, fileName=None, filterChannelNames=False, fid=None, minimal=0): @@ -159,16 +160,15 @@ def __init__(self, fileName=None, filterChannelNames=False, fid=None, minimal=0) self.fid = fid self.zipfile = False if fileName is not None: - self.readinfo(fileName, fid, minimal) + self.read_info(fileName, fid, minimal) - - def readinfo(self, fileName=None, fid=None, minimal=0): + def read_info(self, file_name=None, fid=None, minimal=0): """ Reads MDF file and extracts its complete structure Parameters ---------------- - fileName : str, optional + file_name : str, optional file name. If not input, uses fileName attribute fid : file identifier, optional minimal : int @@ -177,8 +177,8 @@ def readinfo(self, fileName=None, fid=None, minimal=0): 2 will load only DG """ - if self.fileName is None or fileName is not None: - self.fileName = fileName + if self.fileName is None or file_name is not None: + self.fileName = file_name # Open file if self.fid is None or (self.fid is not None and self.fid.closed): @@ -186,22 +186,22 @@ def readinfo(self, fileName=None, fid=None, minimal=0): # read Identifier block self.fid.seek(28) - MDFVersionNumber = unpack('>> import mdfreader - >>> yop=mdfreader.mdf('NameOfFile') + >>> yop=mdfreader.Mdf('NameOfFile') >>> yop.keys() # list channels names # list channels grouped by raster or master channel >>> yop.masterChannelList >>> yop.plot('channelName') or yop.plot({'channel1','channel2'}) - >>> yop.resample(0.1) or yop.resample(channelName='master3') - >>> yop.exportoCSV(sampling=0.01) - >>> yop.exportNetCDF() - >>> yop.exporttoHDF5() - >>> yop.exporttoMatlab() - >>> yop.exporttoExcel() - >>> yop.exporttoXlsx() - >>> yop.convertToPandas() # converts data groups into pandas dataframes + >>> yop.resample(0.1) or yop.resample() + >>> yop.export_to_csv(sampling=0.01) + >>> yop.export_to_NetCDF() + >>> yop.export_to_hdf5() + >>> yop.export_to_matlab() + >>> yop.export_to_excel() + >>> yop.export_to_xlsx() + >>> yop.convert_to_pandas() # converts data groups into pandas dataframes >>> yop.write() # writes mdf file # drops all the channels except the one in argument - >>> yop.keepChannels({'channel1','channel2','channel3'}) - >>> yop.getChannelData('channelName') # returns channel numpy array + >>> yop.keep_channels({'channel1','channel2','channel3'}) + >>> yop.get_channel_data('channelName') # returns channel numpy array """ - def read(self, fileName=None, multiProc=False, channelList=None, - convertAfterRead=True, filterChannelNames=False, - noDataLoading=False, compression=False, metadata=2): + def read(self, file_name=None, multi_processed=False, channel_list=None, convert_after_read=True, + filter_channel_names=False, no_data_loading=False, compression=False, metadata=2): """ reads mdf file version 3.x and 4.x Parameters ---------------- - fileName : str, optional + file_name : str, optional file name - multiProc : bool + multi_processed : bool flag to activate multiprocessing of channel data conversion - channelList : list of str, optional + channel_list : list of str, optional list of channel names to be read If you use channelList, reading might be much slower but it will save you memory. Can be used to read big files - convertAfterRead : bool, optional + convert_after_read : bool, optional flag to convert channel after read, True by default If you use convertAfterRead by setting it to false, all data from channels will be kept raw, no conversion applied. If many float are stored in file, you can gain from 3 to 4 times memory footprint To calculate value from channel, you can then use method .getChannelData() - filterChannelNames : bool, optional + filter_channel_names : bool, optional flag to filter long channel names from its module names separated by '.' - noDataLoading : bool, optional + no_data_loading : bool, optional Flag to read only file info but no data to have minimum memory use compression : bool or str, optional @@ -384,44 +383,44 @@ def read(self, fileName=None, multiProc=False, channelList=None, You should better multi process instances of mdf rather than using multiproc in mdf class (see implementation of mdfconverter) """ - if self.fileName is None or fileName is not None: - self.fileName = fileName + if self.fileName is None or file_name is not None: + self.fileName = file_name # Open file (self.fid, self.fileName, self.zipfile) = _open_mdf(self.fileName) # read Identifier block self.fid.seek(28) - MDFVersionNumber = unpack(' 5: - minTime.append(masterData[0]) - maxTime.append(masterData[-1]) - length.append(len(masterData)) - if minTime: # at least 1 datagroup has a master channel to be resampled - if samplingTime is None: - masterData = linspace(min(minTime), max(maxTime), num=max(length)) + if master in self and len(master_data) > 5: + min_time.append(master_data[0]) + max_time.append(master_data[-1]) + length.append(len(master_data)) + if min_time: # at least 1 datagroup has a master channel to be resampled + if sampling_time is None: + master_data = linspace(min(min_time), max(max_time), num=max(length)) else: - masterData = arange(min(minTime), max(maxTime), samplingTime) - self.add_channel(masterChannelName, masterData, masterChannelName, + master_data = arange(min(min_time), max(max_time), sampling_time) + self.add_channel(master_channel_name, master_data, master_channel_name, master_type=self.get_channel_master_type(master), unit=self.get_channel_unit(master), description=self.get_channel_desc(master), conversion=None) else: - masterChannelName = masterChannel # master channel defined in argument - if masterChannel not in list(self.masterChannelList.keys()): + master_channel_name = master_channel # master channel defined in argument + if master_channel not in list(self.masterChannelList.keys()): warn('master channel name not in existing') raise ValueError('Master Channel not existing') # resample all channels to one sampling time vector if len(list(self.masterChannelList.keys())) > 1: # Not yet resampled or only 1 datagroup # create master channel if not proposed - if masterChannel is None and masterData is not None: - self.add_channel(masterChannelName, masterData, masterChannelName, + if master_channel is None and master_data is not None: + self.add_channel(master_channel_name, master_data, master_channel_name, master_type=self.get_channel_master_type(master), unit=self.get_channel_unit(master), description=self.get_channel_desc(master), conversion=None) # Interpolate channels - timevect = [] - if masterChannelName in self: - masterData = self.getChannelData(masterChannelName) - if masterData is None: # no master channel, cannot resample + time_vect = [] + if master_channel_name in self: + master_data = self.get_channel_data(master_channel_name) + if master_data is None: # no master channel, cannot resample return None for Name in list(self.keys()): try: if Name not in list(self.masterChannelList.keys()): # not a master channel - timevect = self.getChannelData(self.get_channel_master(Name)) - if not self.getChannelData(Name).dtype.kind in ('S', 'U', 'V'): + time_vect = self.get_channel_data(self.get_channel_master(Name)) + if not self.get_channel_data(Name).dtype.kind in ('S', 'U', 'V'): # if channel not array of string self.set_channel_data(Name, - interpolate(masterData, timevect, self.getChannelData(Name))) - self.set_channel_master(Name, masterChannelName) + interpolate(master_data, time_vect, self.get_channel_data(Name))) + self.set_channel_master(Name, master_channel_name) self.set_channel_master_type(Name, self.get_channel_master_type(master)) self.remove_channel_conversion(Name) else: # can not interpolate strings, remove channel containing string self.remove_channel(Name) except: - if timevect is not None and len(timevect) != len(self.getChannelData(Name)): + if time_vect is not None and len(time_vect) != len(self.get_channel_data(Name)): warn('{} and master channel {} do not have same length'. format(Name, self.get_channel_master(Name))) - elif not all(diff(timevect) > 0): + elif not all(diff(time_vect) > 0): master = self.get_channel_master(Name) warn('{} has non regularly increasing master channel {}.\n' ' Faulty samples will be dropped in related data group'. @@ -667,21 +666,21 @@ def interpolate(new_x, x, y): self._clean_uneven_master_data(master) # remove time channels in masterChannelList for ind in list(self.masterChannelList.keys()): - if ind != masterChannelName and ind in self: + if ind != master_channel_name and ind in self: self.remove_channel(ind) self.masterChannelList = {} # empty dict - self.masterChannelList[masterChannelName] = list(self.keys()) - elif len(list(self.masterChannelList.keys())) == 1 and samplingTime is not None: + self.masterChannelList[master_channel_name] = list(self.keys()) + elif len(list(self.masterChannelList.keys())) == 1 and sampling_time is not None: # resamples only 1 datagroup - masterData = self.getChannelData(list(self.masterChannelList.keys())[0]) - masterData = arange(masterData[0], masterData[-1], samplingTime) + master_data = self.get_channel_data(list(self.masterChannelList.keys())[0]) + master_data = arange(master_data[0], master_data[-1], sampling_time) for Name in list(self.keys()): - timevect = self.getChannelData(self.get_channel_master(Name)) - self.set_channel_data(Name, interpolate(masterData, timevect, self.getChannelData(Name))) - self.set_channel_master(Name, masterChannelName) + time_vect = self.get_channel_data(self.get_channel_master(Name)) + self.set_channel_data(Name, interpolate(master_data, time_vect, self.get_channel_data(Name))) + self.set_channel_master(Name, master_channel_name) self.set_channel_master_type(Name, self.get_channel_master_type(master)) self.remove_channel_conversion(Name) - elif samplingTime is None: + elif sampling_time is None: warn('Already resampled') else: warn('no data to be resampled') @@ -696,10 +695,10 @@ def _clean_uneven_master_data(self, master_channel_name): """ # create mask - mask = diff(self.getChannelData(master_channel_name)) > 0 + mask = diff(self.get_channel_data(master_channel_name)) > 0 # remove samples from data group defined by mask for channel in self.masterChannelList[master_channel_name]: - data = self.getChannelData(channel).view(MaskedArray) + data = self.get_channel_data(channel).view(MaskedArray) data.mask = mask self.set_channel_data(channel, data.compressed()) @@ -725,31 +724,31 @@ def cut(self, begin=None, end=None): for master in self.masterChannelList: # for each channel group # find corresponding indexes to cut - masterData = self.getChannelData(master) - if masterData is not None and len(masterData) > 0: # not empty data + master_data = self.get_channel_data(master) + if master_data is not None and len(master_data) > 0: # not empty data if begin is not None: - startIndex = searchsorted(masterData, begin, side='left') + start_index = searchsorted(master_data, begin, side='left') else: - startIndex = 0 + start_index = 0 if end is not None: - endIndex = searchsorted(masterData, end, side='right') + end_index = searchsorted(master_data, end, side='right') else: - endIndex = len(masterData) - if startIndex == endIndex: + end_index = len(master_data) + if start_index == end_index: # empty array for channel in self.masterChannelList[master]: self.set_channel_data(channel, array([])) else: for channel in self.masterChannelList[master]: - data = self.getChannelData(channel) - self.set_channel_data(channel, data[startIndex: endIndex]) + data = self.get_channel_data(channel) + self.set_channel_data(channel, data[start_index: end_index]) - def exportToCSV(self, filename=None, sampling=None): + def export_to_csv(self, file_name=None, sampling=None): """Exports mdf data into CSV file Parameters ---------------- - filename : str, optional + file_name : str, optional file name. If no name defined, it will use original mdf name and path sampling : float, optional @@ -764,9 +763,9 @@ def exportToCSV(self, filename=None, sampling=None): if self: # data in mdf import csv self.resample(sampling) - if filename is None: - filename = splitext(self.fileName)[0] - filename = filename + '.csv' + if file_name is None: + file_name = splitext(self.fileName)[0] + file_name = file_name + '.csv' if self.MDFVersionNumber >= 400: encoding = 'utf8' # mdf4 encoding is unicode else: @@ -775,10 +774,10 @@ def exportToCSV(self, filename=None, sampling=None): if PythonVersion < 3: units = [] names = [] - f = open(filename, "wb") + f = open(file_name, "wb") writer = csv.writer(f, dialect=csv.excel) for name in list(self.keys()): - data = self.getChannelData(name) + data = self.get_channel_data(name) unit = self.get_channel_unit(name) if data.dtype.kind not in ('S', 'U', 'V') \ and data.ndim <= 1: @@ -799,20 +798,20 @@ def exportToCSV(self, filename=None, sampling=None): writer.writerow(names) # writes channel names writer.writerow(units) # writes units else: - f = open(filename, "wt", encoding=encoding) + f = open(file_name, "wt", encoding=encoding) writer = csv.writer(f, dialect=csv.excel) writer.writerow([name for name in list(self.keys()) - if self.getChannelData(name).dtype.kind not in ('S', 'U', 'V') - and self.getChannelData(name).ndim <= 1]) # writes channel names + if self.get_channel_data(name).dtype.kind not in ('S', 'U', 'V') + and self.get_channel_data(name).ndim <= 1]) # writes channel names # writes units writer.writerow([self.get_channel_unit(name) for name in list(self.keys()) - if self.getChannelData(name).dtype.kind not in ('S', 'U', 'V') - and self.getChannelData(name).ndim <= 1]) # writes units + if self.get_channel_data(name).dtype.kind not in ('S', 'U', 'V') + and self.get_channel_data(name).ndim <= 1]) # writes units # concatenate all channels temp = [] for name in list(self.keys()): - data = self.getChannelData(name) + data = self.get_channel_data(name) if data.dtype.kind not in ('S', 'U', 'V') \ and data.ndim <= 1: temp.append(data.transpose()) @@ -826,12 +825,12 @@ def exportToCSV(self, filename=None, sampling=None): else: warn('no data to be exported') - def exportToNetCDF(self, filename=None, sampling=None): + def export_to_NetCDF(self, file_name=None, sampling=None): """Exports mdf data into netcdf file Parameters ---------------- - filename : str, optional + file_name : str, optional file name. If no name defined, it will use original mdf name and path sampling : float, optional @@ -843,87 +842,87 @@ def exportToNetCDF(self, filename=None, sampling=None): """ try: from scipy.io import netcdf - except: - raise ImportError('scipy.io module not found') + except ImportError: + warn('scipy.io module not found') - def cleanName(name): - allowedStr = ' ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+_.@' + def clean_name(name): + allowed_str = ' ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+_.@' buf = '' for c in name: - if c in allowedStr: + if c in allowed_str: buf += c return buf - def setAttribute(f, name, value): + def set_attribute(f, name, value): if value is not None and len(value) > 0: # netcdf does not allow empty strings... if value is dict and 'name' in value: value = value['name'] if PythonVersion >= 3 and value is bytes: value = value.encode('utf-8', 'ignore') - value = cleanName(value) + value = clean_name(value) setattr(f, name, value) else: pass if sampling is not None: self.resample(sampling) - if filename is None: - filename = splitext(self.fileName)[0] - filename = filename + '.nc' - f = netcdf.netcdf_file(filename, 'w') - setAttribute(f, 'Date', self.file_metadata['date']) - setAttribute(f, 'Time', self.file_metadata['time']) - setAttribute(f, 'Author', self.file_metadata['author']) - setAttribute(f, 'Organization', self.file_metadata['organisation']) - setAttribute(f, 'ProjectName', self.file_metadata['project']) - setAttribute(f, 'Subject', self.file_metadata['subject']) - setAttribute(f, 'Comment', self.file_metadata['comment']) + if file_name is None: + file_name = splitext(self.fileName)[0] + file_name = file_name + '.nc' + f = netcdf.netcdf_file(file_name, 'w') + set_attribute(f, 'Date', self.file_metadata['date']) + set_attribute(f, 'Time', self.file_metadata['time']) + set_attribute(f, 'Author', self.file_metadata['author']) + set_attribute(f, 'Organization', self.file_metadata['organisation']) + set_attribute(f, 'ProjectName', self.file_metadata['project']) + set_attribute(f, 'Subject', self.file_metadata['subject']) + set_attribute(f, 'Comment', self.file_metadata['comment']) # Create dimensions having name of all time channels for master in list(self.masterChannelList.keys()): - f.createDimension(master, len(self.getChannelData(self.masterChannelList[master][0]))) + f.createDimension(master, len(self.get_channel_data(self.masterChannelList[master][0]))) # Create variables definition, dimension and attributes var = {} for name in list(self.keys()): - data = self.getChannelData(name) + data = self.get_channel_data(name) if data.dtype == 'float64': - dataType = 'd' + data_type = 'd' elif data.dtype == 'float32': - dataType = 'f' + data_type = 'f' elif data.dtype in ['int8', 'int16', 'uint8', 'uint16']: - dataType = 'h' + data_type = 'h' elif data.dtype in ['int32', 'uint32']: - dataType = 'i' + data_type = 'i' elif data.dtype.kind in ['S', 'U']: - dataType = 'c' + data_type = 'c' else: - dataType = None + data_type = None warn('Can not process numpy type {} of channel {}'.format(data.dtype, name)) - if dataType is not None: + if data_type is not None: # create variable - CleanedName = cleanName(name) + cleaned_name = clean_name(name) if len(list(self.masterChannelList.keys())) == 1: # mdf resampled - var[name] = f.createVariable(CleanedName, dataType, (list(self.masterChannelList.keys())[0], )) + var[name] = f.createVariable(cleaned_name, data_type, (list(self.masterChannelList.keys())[0], )) else: # not resampled - var[name] = f.createVariable(CleanedName, dataType, (self.get_channel_master(name),)) + var[name] = f.createVariable(cleaned_name, data_type, (self.get_channel_master(name),)) # Create attributes - setAttribute(var[name], 'title', CleanedName) - setAttribute(var[name], 'units', self.get_channel_unit(name)) - setAttribute(var[name], 'Description', self.get_channel_desc(name)) + set_attribute(var[name], 'title', cleaned_name) + set_attribute(var[name], 'units', self.get_channel_unit(name)) + set_attribute(var[name], 'Description', self.get_channel_desc(name)) if name in set(self.masterChannelList.keys()): - setAttribute(var[name], 'Type', 'Master Channel') - setAttribute(var[name], 'datatype', 'master') + set_attribute(var[name], 'Type', 'Master Channel') + set_attribute(var[name], 'datatype', 'master') else: - setAttribute(var[name], 'Type', 'Data Channel') + set_attribute(var[name], 'Type', 'Data Channel') # put data in variables for name in list(self.keys()): - var[name] = self.getChannelData(name) + var[name] = self.get_channel_data(name) f.close() - def exportToHDF5(self, filename=None, sampling=None, compression=None, compression_opts=None): + def export_to_hdf5(self, file_name=None, sampling=None, compression=None, compression_opts=None): """Exports mdf class data structure into hdf5 file Parameters ---------------- - filename : str, optional + file_name : str, optional file name. If no name defined, it will use original mdf name and path sampling : float, optional @@ -948,10 +947,10 @@ def exportToHDF5(self, filename=None, sampling=None, compression=None, compressi try: import h5py import os - except: - raise ImportError('h5py not found') + except ImportError: + warn('h5py not found') - def setAttribute(obj, name, value): + def set_attribute(obj, name, value): if value is not None and len(value) > 0: try: if value is dict and 'name' in value: @@ -963,9 +962,9 @@ def setAttribute(obj, name, value): pass if sampling is not None: self.resample(sampling) - if filename is None: - filename = splitext(self.fileName)[0] - filename = filename + '.hdf' + if file_name is None: + file_name = splitext(self.fileName)[0] + file_name = file_name + '.hdf' if compression is not None: compression = compression.lower() if compression not in ['gzip', 'lzf']: @@ -978,71 +977,71 @@ def setAttribute(obj, name, value): else: compression_opts = None - f = h5py.File(filename, 'w') # create hdf5 file + f = h5py.File(file_name, 'w') # create hdf5 file # create group in root associated to file - filegroup = f.create_group(os.path.basename(filename)) - setAttribute(filegroup, 'Author', self.file_metadata['author']) - setAttribute(filegroup, 'Date', self.file_metadata['date']) - setAttribute(filegroup, 'Time', self.file_metadata['time']) - setAttribute(filegroup, 'Time', self.file_metadata['time']) - setAttribute(filegroup, 'Organization', self.file_metadata['organisation']) - setAttribute(filegroup, 'ProjectName', self.file_metadata['project']) - setAttribute(filegroup, 'Subject', self.file_metadata['subject']) - setAttribute(filegroup, 'Comment', self.file_metadata['comment']) - masterTypeDict = {0: 'None', 1: 'Time', 2: 'Angle', 3: 'Distance', 4: 'Index', None: 'None'} + file_group = f.create_group(os.path.basename(file_name)) + set_attribute(file_group, 'Author', self.file_metadata['author']) + set_attribute(file_group, 'Date', self.file_metadata['date']) + set_attribute(file_group, 'Time', self.file_metadata['time']) + set_attribute(file_group, 'Time', self.file_metadata['time']) + set_attribute(file_group, 'Organization', self.file_metadata['organisation']) + set_attribute(file_group, 'ProjectName', self.file_metadata['project']) + set_attribute(file_group, 'Subject', self.file_metadata['subject']) + set_attribute(file_group, 'Comment', self.file_metadata['comment']) + master_type_dict = {0: 'None', 1: 'Time', 2: 'Angle', 3: 'Distance', 4: 'Index', None: 'None'} if len(list(self.masterChannelList.keys())) > 1: # if several time groups of channels, not resampled groups = {} - ngroups = 0 + n_groups = 0 grp = {} for channel in list(self.keys()): - channelData = self.getChannelData(channel) - masterName = self.get_channel_master(channel) - if masterField in self[channel] and masterName not in list(groups.keys()): + channel_data = self.get_channel_data(channel) + master_name = self.get_channel_master(channel) + if masterField in self[channel] and master_name not in list(groups.keys()): # create new data group - ngroups += 1 - if masterName != '' \ - and masterName is not None: - group_name = masterName + n_groups += 1 + if master_name != '' \ + and master_name is not None: + group_name = master_name else: - group_name = masterField+str(ngroups) - groups[group_name] = ngroups - grp[ngroups] = filegroup.create_group(group_name) - setAttribute(grp[ngroups], masterField, masterName) - setAttribute(grp[ngroups], masterTypeField, - masterTypeDict[self.get_channel_master_type(channel)]) - elif masterField in self[channel] and masterName in list(groups.keys()): - group_name = masterName - if channelData.dtype.kind not in ('U', 'O'): # not supported type + group_name = masterField+str(n_groups) + groups[group_name] = n_groups + grp[n_groups] = file_group.create_group(group_name) + set_attribute(grp[n_groups], masterField, master_name) + set_attribute(grp[n_groups], masterTypeField, + master_type_dict[self.get_channel_master_type(channel)]) + elif masterField in self[channel] and master_name in list(groups.keys()): + group_name = master_name + if channel_data.dtype.kind not in ('U', 'O'): # not supported type dset = grp[groups[group_name]].create_dataset(channel, - data=channelData, + data=channel_data, compression=compression, compression_opts=compression_opts) - setAttribute(dset, unitField, self.get_channel_unit(channel)) + set_attribute(dset, unitField, self.get_channel_unit(channel)) if descriptionField in self[channel]: - setAttribute(dset, descriptionField, self.get_channel_desc(channel)) + set_attribute(dset, descriptionField, self.get_channel_desc(channel)) else: # resampled or only one time for all channels : no groups - masterName = list(self.masterChannelList.keys())[0] - setAttribute(filegroup, masterField, masterName) - setAttribute(filegroup, masterTypeField, - masterTypeDict[self.get_channel_master_type(masterName)]) + master_name = list(self.masterChannelList.keys())[0] + set_attribute(file_group, masterField, master_name) + set_attribute(file_group, masterTypeField, + master_type_dict[self.get_channel_master_type(master_name)]) for channel in list(self.keys()): - channelData = self.getChannelData(channel) - if channelData.dtype.kind not in ('U', 'O'): # not supported type - dset = filegroup.create_dataset(channel, data=channelData, - compression=compression, - compression_opts=compression_opts) - setAttribute(dset, unitField, self.get_channel_unit(channel)) + channel_data = self.get_channel_data(channel) + if channel_data.dtype.kind not in ('U', 'O'): # not supported type + dset = file_group.create_dataset(channel, data=channel_data, + compression=compression, + compression_opts=compression_opts) + set_attribute(dset, unitField, self.get_channel_unit(channel)) if descriptionField in self[channel]: - setAttribute(dset, descriptionField, self.get_channel_desc(channel)) + set_attribute(dset, descriptionField, self.get_channel_desc(channel)) f.close() - def exportToMatlab(self, filename=None): + def export_to_matlab(self, file_name=None): """Export mdf data into Matlab file format 5, tentatively compressed Parameters ---------------- - filename : str, optional + file_name : str, optional file name. If no name defined, it will use original mdf name and path Notes @@ -1053,35 +1052,35 @@ def exportToMatlab(self, filename=None): Channels might have then different lengths Dependency: scipy """ - # export class data struture into .mat file + # export class data structure into .mat file try: from scipy.io import savemat except: raise ImportError('scipy module not found') - if filename is None: - filename = splitext(self.fileName)[0] - filename = filename + '.mat' + if file_name is None: + file_name = splitext(self.fileName)[0] + file_name = file_name + '.mat' # convert self into simple dict without and metadata temp = {} for channel in list(self.keys()): - data = self.getChannelData(channel) + data = self.get_channel_data(channel) if data.dtype.kind not in ('S', 'U', 'V'): # does not like special characters chains, skip - channelName = _convertMatlabName(channel) - if len(channelName) > 0 and channelName is not None: - temp[channelName] = data - elif channelName is not None: + channel_name = _convert_to_matlab_name(channel) + if len(channel_name) > 0 and channel_name is not None: + temp[channel_name] = data + elif channel_name is not None: warn(u'Could not export {}, name is not compatible with Matlab'.format(channel)) try: # depends of version used , compression can be used - savemat(filename, temp, long_field_names=True, format='5', do_compression=True, oned_as='column') + savemat(file_name, temp, long_field_names=True, format='5', do_compression=True, oned_as='column') except: - savemat(filename, temp, long_field_names=True, format='5') + savemat(file_name, temp, long_field_names=True, format='5') - def exportToExcel(self, filename=None): + def export_to_excel(self, file_name=None): """Exports mdf data into excel 95 to 2003 file Parameters ---------------- - filename : str, optional + file_name : str, optional file name. If no name defined, it will use original mdf name and path Notes @@ -1098,63 +1097,68 @@ def exportToExcel(self, filename=None): import xlwt3 as xlwt except: raise ImportError('xlwt module missing') - if filename is None: - filename = filename = splitext(self.fileName)[0] - filename = filename + '.xls' - styleText = xlwt.easyxf('font: name Times New Roman, color-index black, bold off') + if file_name is None: + file_name = splitext(self.fileName)[0] + file_name = file_name + '.xls' + style_text = xlwt.easyxf('font: name Times New Roman, color-index black, bold off') coding = 'utf-8' wb = xlwt.Workbook(encoding=coding) - channelList = list(self.keys()) + channel_list = list(self.keys()) if PythonVersion < 3: - Units = [self.get_channel_unit(channel).decode(coding, 'replace') for channel in list(self.keys())] + units = [self.get_channel_unit(channel).decode(coding, 'replace') for channel in list(self.keys())] else: - Units = [self.get_channel_unit(channel) for channel in list(self.keys())] + units = [self.get_channel_unit(channel) for channel in list(self.keys())] # Excel 2003 limits - maxCols = 255 - maxLines = 65535 - workbooknumber = int(ceil(len(channelList) * 1.0 / (maxCols * 1.0))) - tooLongChannels = [] - # split colmuns in several worksheets if more than 256 cols - for workbook in range(workbooknumber): + max_cols = 255 + max_lines = 65535 + workbook_number = int(ceil(len(channel_list) * 1.0 / (max_cols * 1.0))) + too_long_channels = [] + # split columns in several worksheets if more than 256 cols + for workbook in range(workbook_number): ws = wb.add_sheet('Sheet' + str(workbook)) # , cell_overwrite_ok = True ) - if workbook == workbooknumber - 1: # last sheet - columnrange = list(range(workbook * maxCols, len(channelList))) - elif workbook < workbooknumber - 1 and workbooknumber > 1: # first sheets - columnrange = list(range(workbook * maxCols, (workbook + 1) * maxCols)) - for col in columnrange: + if workbook == workbook_number - 1: # last sheet + column_range = list(range(workbook * max_cols, len(channel_list))) + elif workbook < workbook_number - 1 and workbook_number > 1: # first sheets + column_range = list(range(workbook * max_cols, (workbook + 1) * max_cols)) + for col in column_range: # write header - ws.write(0, col - workbook * maxCols, channelList[col], styleText) - ws.write(1, col - workbook * maxCols, Units[col], styleText) - vect = self.getChannelData(channelList[col]) # data vector - if not len(vect) > maxLines: - if vect.dtype.kind not in ['S', 'U']: # if not a string or unicode - [ws.row(row + 2).set_cell_number(col - workbook * maxCols, vect[row]) for row in list(range(len(vect)))] + ws.write(0, col - workbook * max_cols) + ws.write(1, col - workbook * max_cols) + vector = self.get_channel_data(channel_list[col]) # data vector + if not len(vector) > max_lines: + if vector.dtype.kind not in ['S', 'U']: # if not a string or unicode + [ws.row(row + 2).set_cell_number(col - workbook * max_cols, vector[row]) + for row in list(range(len(vector)))] else: # it's a string, cannot write for the moment if PythonVersion < 3: try: - vect = vect.encode(coding) + vector = vector.encode(coding) except: pass - [ws.row(row + 2).set_cell_text(col - workbook * maxCols, vect[row]) for row in list(range(len(vect)))] + [ws.row(row + 2).set_cell_text(col - workbook * max_cols, vector[row]) + for row in list(range(len(vector)))] else: # channel too long, written until max Excel line limit - if vect.dtype.kind not in ['S', 'U']: # if not a string - [ws.row(row + 2).set_cell_number(col - workbook * maxCols, vect[row]) for row in list(range(maxLines))] + if vector.dtype.kind not in ['S', 'U']: # if not a string + [ws.row(row + 2).set_cell_number(col - workbook * max_cols, vector[row]) + for row in list(range(max_lines))] else: # it's a string, cannot write for the moment if PythonVersion < 3: - vect = vect.encode(coding) - [ws.row(row + 2).set_cell_text(col - workbook * maxCols, vect[row]) for row in list(range(maxLines))] - tooLongChannels.append(channelList[col]) # to later warn user the channel is not completely written - wb.save(filename) # writes workbook on HDD - if len(tooLongChannels) > 0: # if not empty, some channels have been not processed + vector = vector.encode(coding) + [ws.row(row + 2).set_cell_text(col - workbook * max_cols, vector[row]) + for row in list(range(max_lines))] + # to later warn user the channel is not completely written + too_long_channels.append(channel_list[col]) + wb.save(file_name) # writes workbook on HDD + if len(too_long_channels) > 0: # if not empty, some channels have been not processed warn('Following channels were too long to be processed completely,' - ' maybe you should resample : {}'.format(tooLongChannels)) + ' maybe you should resample : {}'.format(too_long_channels)) - def exportToXlsx(self, filename=None): + def export_to_xlsx(self, file_name=None): """Exports mdf data into excel 2007 and 2010 file Parameters ---------------- - filename : str, optional + file_name : str, optional file name. If no name defined, it will use original mdf name and path Notes @@ -1165,64 +1169,65 @@ def exportToXlsx(self, filename=None): try: import openpyxl from openpyxl.utils.exceptions import IllegalCharacterError - except: - raise ImportError('Module openpyxl missing') - if filename is None: - filename = splitext(self.fileName)[0] - filename = filename + '.xlsx' + except ImportError: + warn('Module openpyxl missing') + if file_name is None: + file_name = splitext(self.fileName)[0] + file_name = file_name + '.xlsx' warn('Creating Excel sheet') wb = openpyxl.workbook.Workbook() ws = wb.active # get_active_sheet() - ncol = 1 + n_col = 1 for master in self.masterChannelList: channels = self.masterChannelList[master] for channel in channels: - data = self.getChannelData(channel) + data = self.get_channel_data(channel) if data.ndim <= 1: # not an array channel - ws.cell(row=1, column=ncol).value = channel - ws.cell(row=2, column=ncol).value = self.get_channel_unit(channel) + ws.cell(row=1, column=n_col).value = channel + ws.cell(row=2, column=n_col).value = self.get_channel_unit(channel) try: if data.ndim <= 1: # not an array channel if data.dtype.kind in ('i', 'u') or 'f4' in data.dtype.str: for r, cell_data in enumerate(data): - ws.cell(row=r + 3, column=ncol).value = float64(cell_data) + ws.cell(row=r + 3, column=n_col).value = float64(cell_data) elif not data.dtype.kind == 'V': for r, cell_data in enumerate(data): - ws.cell(row=r + 3, column=ncol).value = cell_data + ws.cell(row=r + 3, column=n_col).value = cell_data except IllegalCharacterError: warn(u'could not export {}'.format(channel)) - ncol += 1 + n_col += 1 warn('Writing file, please wait') - wb.save(filename) + wb.save(file_name) - def keepChannels(self, channelList): + def keep_channels(self, channel_list): """ keeps only list of channels and removes the other channels Parameters ---------------- - channelList : list of str + channel_list : list of str list of channel names """ - channelList = [channel for channel in channelList] - removeChannels = [] - channelSet = set(channelList) + channel_list = [channel for channel in channel_list] + remove_channels = [] + channel_set = set(channel_list) for channel in list(self.keys()): - if channel not in channelSet and masterField not in channel and channel not in set(self.masterChannelList.keys()): + if channel not in channel_set and masterField not in channel \ + and channel not in set(self.masterChannelList.keys()): # avoid to remove master channels otherwise problems with resample - removeChannels.append(channel) - if not len(removeChannels) == 0: - [self.masterChannelList[self.get_channel_master(channel)].remove(channel) for channel in removeChannels] - [self.pop(channel) for channel in removeChannels] + remove_channels.append(channel) + if not len(remove_channels) == 0: + [self.masterChannelList[self.get_channel_master(channel)].remove(channel) for channel in remove_channels] + [self.pop(channel) for channel in remove_channels] - def mergeMdf(self, mdfClass): + def merge_mdf(self, mdf_class): """Merges data of 2 mdf classes Parameters ---------------- - mdfClass : mdf + mdf_class : Mdf mdf class instance to be merge with self Notes @@ -1230,30 +1235,30 @@ def mergeMdf(self, mdfClass): both classes must have been resampled, otherwise, impossible to know master channel to match create union of both channel lists and fill with Nan for unknown sections in channels """ - self.convertAllChannel() # make sure all channels are converted + self.convert_all_channel() # make sure all channels are converted if not len(list(self.masterChannelList.keys())) == 1: raise Exception('Data not resampled') - unionedList = list(mdfClass.keys()) and list(self.keys()) - initialTimeSize = len(self.getChannelData('master')) - for channel in unionedList: - if channel in mdfClass and channel in self: # channel exists in both class - data = self.getChannelData(channel) - mdfData = mdfClass.getChannelData(channel) + unioned_list = list(mdf_class.keys()) and list(self.keys()) + initial_time_size = len(self.get_channel_data('master')) + for channel in unioned_list: + if channel in mdf_class and channel in self: # channel exists in both class + data = self.get_channel_data(channel) + mdf_data = mdf_class.get_channel_data(channel) if not channel == 'master': - self.set_channel_data(channel, hstack((data, mdfData))) + self.set_channel_data(channel, hstack((data, mdf_data))) else: - offset = mean(diff(mdfData)) # sampling + offset = mean(diff(mdf_data)) # sampling offset = data[-1] + offset # time offset - self.set_channel_data(channel, hstack((data, mdfData + offset))) - elif channel in mdfClass: # new channel for self from mdfClass - mdfData = mdfClass.getChannelData(channel) - self[channel] = mdfClass[channel] # initialise all fields, units, descriptions, etc. - refill = empty(initialTimeSize) + self.set_channel_data(channel, hstack((data, mdf_data + offset))) + elif channel in mdf_class: # new channel for self from mdfClass + mdf_data = mdf_class.get_channel_data(channel) + self[channel] = mdf_class[channel] # initialise all fields, units, descriptions, etc. + refill = empty(initial_time_size) refill.fil(nan) # fill with NANs - self.set_channel_data(channel, hstack((refill, mdfData))) # readjust against time + self.set_channel_data(channel, hstack((refill, mdf_data))) # readjust against time else: # channel missing in mdfClass - data = self.getChannelData(channel) - refill = empty(len(mdfClass.getChannelData('master'))) + data = self.get_channel_data(channel) + refill = empty(len(mdf_class.get_channel_data('master'))) refill.fill(nan) # fill with NANs self.set_channel_data(channel, hstack((data, refill))) @@ -1265,7 +1270,7 @@ def copy(self): mdf class instance copy of a mdf class """ - yop = mdf() + yop = Mdf() yop.multiProc = self.multiProc yop.fileName = self.fileName yop.masterChannelList = self.masterChannelList @@ -1277,7 +1282,7 @@ def copy(self): yop[channel] = self[channel] return yop - def convertToPandas(self, sampling=None): + def convert_to_pandas(self, sampling=None): """converts mdf data structure into pandas dataframe(s) Parameters @@ -1293,17 +1298,17 @@ def convertToPandas(self, sampling=None): # convert data structure into pandas module try: import pandas as pd - except: - raise ImportError('Module pandas missing') + except ImportError: + warn('Module pandas missing') if sampling is not None: self.resample(sampling) if self.file_metadata['date'] != '' and self.file_metadata['time'] != '': date = self.file_metadata['date'].replace(':', '-') time = self.file_metadata['time'] - datetimeInfo = datetime64(date + 'T' + time) + datetime_info = datetime64(date + 'T' + time) else: - datetimeInfo = datetime64(datetime.now()) - originalKeys = list(self.keys()) + datetime_info = datetime64(datetime.now()) + original_keys = list(self.keys()) for group in self.masterChannelList: if group not in self.masterChannelList[group]: warn('no master channel in group {}'.format(group)) @@ -1313,24 +1318,24 @@ def convertToPandas(self, sampling=None): temp = {} # convert time channel into timedelta if group in self.masterChannelList[group]: - time = datetimeInfo + array(self.getChannelData(group) * 1E6, - dtype='timedelta64[us]') + time = datetime_info + array(self.get_channel_data(group) * 1E6, + dtype='timedelta64[us]') for channel in self.masterChannelList[group]: - data = self.getChannelData(channel) + data = self.get_channel_data(channel) if data.ndim == 1 and data.shape == time.shape \ and not data.dtype.char == 'V': temp[channel] = pd.Series(data, index=time) self[group + '_group'] = pd.DataFrame(temp) self[group + '_group'].pop(group) # delete time channel, no need anymore - else: # no master channel in channel group + else: # no master channel in channel group for channel in self.masterChannelList[group]: - data = self.getChannelData(channel) + data = self.get_channel_data(channel) if data.ndim == 1 and not data.dtype.char == 'V': temp[channel] = pd.Series(data) self[group + '_group'] = pd.DataFrame(temp) # clean rest of self from data and time channel information - [self[channel].pop(dataField) for channel in originalKeys] - [self[channel].pop(masterField) for channel in originalKeys if masterField in self[channel]] + [self[channel].pop(dataField) for channel in original_keys] + [self[channel].pop(masterField) for channel in original_keys if masterField in self[channel]] self.masterGroups = [] # save time groups name in list [self.masterGroups.append(group + '_group') for group in list(self.masterChannelList.keys())] self.masterChannelList = {} @@ -1368,24 +1373,24 @@ def convertToPandas(self, sampling=None): args = parser.parse_args() - temp = mdf(fileName=args.fileName, channelList=args.channelList, + temp = Mdf(fileName=args.fileName, channelList=args.channelList, converAfterRead=args.convertAfterRead, filterChannelNames=args.filterChannelNames, noDataLoading=args.noDataLoading, compression=args.compression) if args.export is not None: if args.export == 'CSV': - temp.exportToCSV() + temp.export_to_csv() elif args.export == 'HDF5': - temp.exportToHDF5() + temp.export_to_hdf5() elif args.export == 'Matlab': - temp.exportToMatlab() + temp.export_to_matlab() elif args.export == 'Xlsx': - temp.exportToXlsx() + temp.export_to_xlsx() elif args.export == 'Excel': - temp.exportToExcel() + temp.export_to_excel() elif args.export == 'NetCDF': - temp.exportToNetCDF() + temp.export_to_NetCDF() elif args.export == 'MDF': temp.write() if args.plot_channel_list is not None: From 56ccb72b5c1f46c65acf51d5ed2cdde3364f71b9 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Wed, 31 Oct 2018 21:49:38 +0100 Subject: [PATCH 33/61] Some pep8 refactoring --- mdfreader/channel.py | 2 +- mdfreader/mdf.py | 8 ++++---- mdfreader/mdf3reader.py | 10 +++++----- mdfreader/mdf4reader.py | 18 +++++++++--------- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/mdfreader/channel.py b/mdfreader/channel.py index d6784b7..cea4e85 100644 --- a/mdfreader/channel.py +++ b/mdfreader/channel.py @@ -26,7 +26,7 @@ class Channel4(object): __slots__ = ['channelNumber', 'channelGroup', 'dataGroup', - 'type', 'name', 'VLSD_CG_Flag', 'nBytes', 'byteOffset', 'bit_masking_needed'] + 'type', 'name', 'VLSD_CG_Flag', 'nBytes', 'byteOffset'] """ channel class gathers all about channel structure in a record Attributes diff --git a/mdfreader/mdf.py b/mdfreader/mdf.py index 225c368..1710844 100644 --- a/mdfreader/mdf.py +++ b/mdfreader/mdf.py @@ -150,10 +150,10 @@ def __init__(self, fileName=None, channelList=None, convertAfterRead=True, self.clear() self.fileName = fileName if fileName is not None: - self.read(fileName, channelList=channelList, - convertAfterRead=convertAfterRead, - filterChannelNames=filterChannelNames, - noDataLoading=noDataLoading, + self.read(fileName, channel_list=channelList, + convert_after_read=convertAfterRead, + filter_channel_names=filterChannelNames, + no_data_loading=noDataLoading, compression=compression, metadata=metadata) diff --git a/mdfreader/mdf3reader.py b/mdfreader/mdf3reader.py index d7ca0e9..3ff3047 100644 --- a/mdfreader/mdf3reader.py +++ b/mdfreader/mdf3reader.py @@ -659,13 +659,13 @@ class DATA(dict): Methods ------------ - addRecord(record) + add_record(record) Adds a new record in DATA class dict read(channelSet) Reads data block - loadSorted(record, nameList=None) + load_sorted(record, nameList=None) Reads sorted data block from record definition - loadUnSorted(nameList=None) + load_unsorted(nameList=None) Reads unsorted data block, not yet implemented """ @@ -838,7 +838,7 @@ def read3(self, file_name=None, info=None, multi_processed=False, channel_list=N If you use convertAfterRead by setting it to false, all data from channels will be kept raw, no conversion applied. If many float are stored in file, you can gain from 3 to 4 times memory footprint - To calculate value from channel, you can then use method .getChannelData() + To calculate value from channel, you can then use method .get_channel_data() filter_channel_names : bool, optional flag to filter long channel names from its module names separated by '.' @@ -958,7 +958,7 @@ def read3(self, file_name=None, info=None, multi_processed=False, channel_list=N # Process concatenated bits inside uint8 if chan.bit_masking_needed: # if channel data do not use complete bytes - if chan.signal_data_type in (0, 1, 9, 10, 13, 14): # integers + if chan.signalDataType in (0, 1, 9, 10, 13, 14): # integers temp = right_shift(temp, chan.embedding_channel_bitOffset) mask = int(pow(2, chan.bitCount) - 1) # masks isBitUint8 temp = bitwise_and(temp, mask) diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index abd5c3b..ce9667a 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -689,7 +689,7 @@ def load_info(self, info): and channel_pos_bit_end <= 8 * (prev_chan_byte_offset + prev_chan_n_bytes) if embedding_channel is not None: embedding_channel_includes_curr_chan = \ - channel_pos_bit_end <= embedding_channel.posByteEnd(info) * 8 + channel_pos_bit_end <= embedding_channel.pos_byte_end(info) * 8 else: embedding_channel_includes_curr_chan = False if channel.byteOffset >= prev_chan_byte_offset and \ @@ -698,7 +698,7 @@ def load_info(self, info): # not byte aligned self.byte_aligned = False if embedding_channel is not None and \ - channel_pos_bit_end > embedding_channel.posByteEnd(info) * 8: + channel_pos_bit_end > embedding_channel.pos_byte_end(info) * 8: embedding_channel = None if prev_chan_includes_curr_chan or \ embedding_channel_includes_curr_chan: # bit(s) in byte(s) @@ -961,17 +961,17 @@ def read_channels_from_bytes(self, bit_stream, info, channel_set=None, n_records if dataRead_available: # use rather cython compiled code for performance bytesdata = bytes(bit_stream) for chan in channels_indexes: - if self[chan].isCABlock(info): + if self[chan].is_ca_block(info): ca = self[chan].CABlock(info) array_flag = ca['ca_ndim'] else: array_flag = 0 buf[self[chan].name] = \ - dataRead(bytesdata, self[chan].bitCount(info), - self[chan].signalDataType(info), - self[chan].nativedataFormat(info), + dataRead(bytesdata, self[chan].bit_count(info), + self[chan].signal_data_type(info), + self[chan].native_data_format(info), n_records, self.CGrecordLength, - self[chan].bitOffset(info), self[chan].posByteBeg(info), + self[chan].bit_offset(info), self[chan].pos_byte_beg(info), self[chan].nBytes, array_flag) return buf else: @@ -1144,7 +1144,7 @@ def read4(self, file_name=None, info=None, multi_processed=False, channel_list=N If you use convertAfterRead by setting it to false, all data from channels will be kept raw, no conversion applied. If many float are stored in file, you can gain from 3 to 4 times memory footprint - To calculate value from channel, you can then use method .getChannelData() + To calculate value from channel, you can then use method .get_channel_data() compression : bool, optional flag to activate data compression with blosc @@ -1605,7 +1605,7 @@ def write4(self, file_name=None, compression=False): data_list = () last_channel = 0 for n_channel, channel in enumerate(self.masterChannelList[masterChannel]): - data = self.getChannelData(channel) + data = self.get_channel_data(channel) # no interest to write invalid bytes as channel, should be processed if needed before writing if channel.find('invalid_bytes') == -1 and data is not None and len(data) > 0: last_channel = n_channel From 74db136247f38264a76e15cf18347e9d8d3d3f03 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Wed, 31 Oct 2018 21:56:29 +0100 Subject: [PATCH 34/61] Some pep8 refactoring --- mdfreader/mdf4reader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index ce9667a..78468d2 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -153,7 +153,7 @@ def _read_unsorted(record, info, parent_block, channel_set=None): record_id = record_id_c_format.unpack(parent_block['data'][position:position + record_id_size])[0] if not record[record_id]['record'].Flags & 0b1: # not VLSD CG) temp = record.read_record(record_id, info, parent_block['data'][position:position + record[record_id][ - 'record'].CGrecordLength + 1], channel_set) + 'record'].CGrecordLength + 1]) position += record[record_id]['record'].CGrecordLength for channelName in temp: buf[channelName].append(temp[channelName]) From e0bcb2f1b6e67485963b622ef845be43fc0897d6 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Wed, 31 Oct 2018 22:04:54 +0100 Subject: [PATCH 35/61] Some pep8 refactoring --- mdfreader/mdf3reader.py | 2 +- mdfreader/mdf4reader.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mdfreader/mdf3reader.py b/mdfreader/mdf3reader.py index 3ff3047..c6e5d35 100644 --- a/mdfreader/mdf3reader.py +++ b/mdfreader/mdf3reader.py @@ -530,7 +530,7 @@ def read_sorted_record(self, fid, pointer, channel_set=None): rec[chan.name][previous_index: previous_index + n_record_chunk] = \ dataRead(bytes(bit_stream), chan.bitCount, - convertDataType3to4[chan.signal_data_type], + convertDataType3to4[chan.signalDataType], chan.nativedataFormat, n_record_chunk, self.CGrecordLength, diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index 78468d2..3b435df 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -962,7 +962,7 @@ def read_channels_from_bytes(self, bit_stream, info, channel_set=None, n_records bytesdata = bytes(bit_stream) for chan in channels_indexes: if self[chan].is_ca_block(info): - ca = self[chan].CABlock(info) + ca = self[chan].ca_block(info) array_flag = ca['ca_ndim'] else: array_flag = 0 From a80840f233c1bfb4b4651d54f6aac833cb9fef33 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Wed, 31 Oct 2018 22:12:00 +0100 Subject: [PATCH 36/61] Some pep8 refactoring --- mdfreader/mdf3reader.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mdfreader/mdf3reader.py b/mdfreader/mdf3reader.py index c6e5d35..a738428 100644 --- a/mdfreader/mdf3reader.py +++ b/mdfreader/mdf3reader.py @@ -623,12 +623,12 @@ def signed_int(temp, extension): if not nbytes == Channel.nBytes: byte = bitarray(8 * (Channel.nBytes - nbytes), endian='little') byte.setall(False) - if Channel.signal_data_type not in (1, 10, 14): # not signed integer + if Channel.signalDataType not in (1, 10, 14): # not signed integer temp[Channel.name].extend(byte) else: # signed integer (two's complement), keep sign bit and extend with bytes temp[Channel.name] = signed_int(temp[Channel.name], byte) n_trail_bits = Channel.nBytes*8 - Channel.bitCount - if Channel.signal_data_type in (1, 10, 14) and \ + if Channel.signalDataType in (1, 10, 14) and \ nbytes == Channel.nBytes and \ n_trail_bits > 0: # Ctype byte length but signed integer trail_bits = bitarray(n_trail_bits, endian='little') From 0c398a66dbbdd67abeb5858f636724a2625fbff1 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Wed, 31 Oct 2018 22:32:00 +0100 Subject: [PATCH 37/61] Some pep8 refactoring --- mdfreader/mdf.py | 32 ++++++++++++++++---------------- mdfreader/mdf3reader.py | 8 ++++---- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/mdfreader/mdf.py b/mdfreader/mdf.py index 1710844..ef7b09c 100644 --- a/mdfreader/mdf.py +++ b/mdfreader/mdf.py @@ -93,22 +93,22 @@ class MdfSkeleton(dict): adds basic metadata from file """ - def __init__(self, fileName=None, channelList=None, convertAfterRead=True, - filterChannelNames=False, noDataLoading=False, - compression=False, convertTables=False, metadata=2): + def __init__(self, file_name=None, channel_list=None, convert_after_read=True, + filter_channel_names=False, no_data_loading=False, + compression=False, convert_tables=False, metadata=2): """ mdf_skeleton class constructor. Parameters ---------------- - fileName : str, optional + file_name : str, optional file name - channelList : list of str, optional + channel_list : list of str, optional list of channel names to be read If you use channelList, reading might be much slower but it will save you memory. Can be used to read big files. - convertAfterRead : bool, optional + convert_after_read : bool, optional flag to convert channel after read, True by default If you use convertAfterRead by setting it to false, all data from channels will be kept raw, no conversion applied. @@ -117,12 +117,12 @@ def __init__(self, fileName=None, channelList=None, convertAfterRead=True, To calculate value from channel, you can then use method .get_channel_data() - filterChannelNames : bool, optional + filter_channel_names : bool, optional flag to filter long channel names from its module names separated by '.' compression : bool optional flag to compress data in memory - convertTables : bool, optional, default False + convert_tables : bool, optional, default False flag to convert or not only conversions with tables. These conversions types take generally long time and memory """ @@ -139,21 +139,21 @@ def __init__(self, fileName=None, channelList=None, convertAfterRead=True, self.file_metadata['time'] = '' self.file_metadata['date'] = '' self.MDFVersionNumber = 300 - self.filterChannelNames = filterChannelNames + self.filterChannelNames = filter_channel_names # by default, do not convert table conversion types, taking lot of time and memory - self.convert_tables = convertTables + self.convert_tables = convert_tables self._pandasframe = False self.info = None self._compression_level = 9 # default compression level self._noDataLoading = False # in case reading with this argument activated # clears class from previous reading and avoid to mess up self.clear() - self.fileName = fileName - if fileName is not None: - self.read(fileName, channel_list=channelList, - convert_after_read=convertAfterRead, - filter_channel_names=filterChannelNames, - no_data_loading=noDataLoading, + self.fileName = file_name + if file_name is not None: + self.read(file_name, channel_list=channel_list, + convert_after_read=convert_after_read, + filter_channel_names=filter_channel_names, + no_data_loading=no_data_loading, compression=compression, metadata=metadata) diff --git a/mdfreader/mdf3reader.py b/mdfreader/mdf3reader.py index a738428..70f7137 100644 --- a/mdfreader/mdf3reader.py +++ b/mdfreader/mdf3reader.py @@ -619,9 +619,9 @@ def signed_int(temp, extension): for Channel in self: # list of channel classes from channelSet if Channel.name in channel_set: temp[Channel.name] = B[Channel.posBitBeg: Channel.posBitEnd] - nbytes = len(temp[Channel.name].tobytes()) - if not nbytes == Channel.nBytes: - byte = bitarray(8 * (Channel.nBytes - nbytes), endian='little') + n_bytes = len(temp[Channel.name].tobytes()) + if not n_bytes == Channel.nBytes: + byte = bitarray(8 * (Channel.nBytes - n_bytes), endian='little') byte.setall(False) if Channel.signalDataType not in (1, 10, 14): # not signed integer temp[Channel.name].extend(byte) @@ -629,7 +629,7 @@ def signed_int(temp, extension): temp[Channel.name] = signed_int(temp[Channel.name], byte) n_trail_bits = Channel.nBytes*8 - Channel.bitCount if Channel.signalDataType in (1, 10, 14) and \ - nbytes == Channel.nBytes and \ + n_bytes == Channel.nBytes and \ n_trail_bits > 0: # Ctype byte length but signed integer trail_bits = bitarray(n_trail_bits, endian='little') temp[Channel.name] = signed_int(temp[Channel.name], trail_bits) From 6cce36784991a37e555e7c9d8c87cac92dd9e284 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Wed, 31 Oct 2018 22:59:18 +0100 Subject: [PATCH 38/61] updated docs after pep8 refactoring --- docs/mdfreader.pdf | Bin 234333 -> 222608 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/mdfreader.pdf b/docs/mdfreader.pdf index 264377014e090ef0bc8d805dd24c0d3ed3977a3f..448498e9305796fd72c7e2664993b09c00bc1b23 100644 GIT binary patch delta 188721 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

)rlMEB5w{QHB~IuJj* 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

OteCob6V<|WidU~in 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¬FEnf{-^|LX; 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 From afbe683d171febac95c33f19a3ed18e3fcef3f30 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Thu, 1 Nov 2018 19:13:24 +0100 Subject: [PATCH 50/61] Some pep8 refactoring --- mdfreader/channel.py | 27 ++++++++++++--------------- mdfreader/mdf3reader.py | 2 +- mdfreader/mdf4reader.py | 33 ++++++++++++++++----------------- mdfreader/mdfinfo3.py | 2 +- mdfreader/mdfinfo4.py | 2 +- mdfreader/mdfreader.py | 12 ++++++------ 6 files changed, 37 insertions(+), 41 deletions(-) diff --git a/mdfreader/channel.py b/mdfreader/channel.py index 91ec19c..bed6564 100644 --- a/mdfreader/channel.py +++ b/mdfreader/channel.py @@ -49,7 +49,7 @@ class Channel4(object): byteOffset : int byte offset in record bit_masking_needed : boolean - + Methods ------------ @@ -154,7 +154,7 @@ def __init__(self): self.VLSD_CG_Flag = False self.nBytes = 0 self.byteOffset = 0 - #self.bit_masking_needed = True + # self.bit_masking_needed = True def __str__(self): """ channel object attributes print @@ -184,8 +184,7 @@ def attachment(self, fid, info): ATBlock class from mdfinfo4 module """ try: - return ATBlock(fid, info['CN'][self.dataGroup][self.channelGroup]\ - [self.channelNumber]['cn_data']) + return ATBlock(fid, info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_data']) except KeyError: print('No Attachment block for this channel') @@ -244,8 +243,7 @@ def signal_data_type(self, info, byte_aligned=True): 14 CANopen time """ if not self.type == 4: # Invalid bit channel - return info['CN'][self.dataGroup][self.channelGroup]\ - [self.channelNumber]['cn_data_type'] + return info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_data_type'] else: if byte_aligned: return 10 # byte array @@ -301,8 +299,7 @@ def channel_sync_type(self, info): 4 index """ try: - return info['CN'][self.dataGroup][self.channelGroup]\ - [self.channelNumber]['cn_sync_type'] + return info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_sync_type'] except KeyError: return 0 # in case of invalid bytes channel @@ -409,8 +406,8 @@ def calc_bytes(self, info): """ if not self.type == 4: # not channel containing invalid bit n_bytes = _bits_to_bytes(info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_bit_count'] - + info['CN'][self.dataGroup][self.channelGroup][self.channelNumber] - ['cn_bit_offset'], self.isnumeric(info)) + + info['CN'][self.dataGroup][self.channelGroup][self.channelNumber] + ['cn_bit_offset'], self.isnumeric(info)) if self.type in (1, 2): # array channel n_bytes *= self.ca_block(info)['PNd'] block = self.ca_block(info) @@ -444,8 +441,7 @@ def little_endian(self, info): ----------- boolean """ - if info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]\ - ['cn_data_type'] in (1, 3, 5, 9): # endianness + if info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_data_type'] in (1, 3, 5, 9): return False else: return True @@ -555,8 +551,9 @@ def c_format(self, info): elif self.type in (1, 2): # array channel ca = self.ca_block(info) n_bytes = _bits_to_bytes(info['CN'][self.dataGroup][self.channelGroup] - [self.channelNumber]['cn_bit_count'] + info['CN'][self.dataGroup][self.channelGroup] - [self.channelNumber]['cn_bit_offset'], self.isnumeric(info)) + [self.channelNumber]['cn_bit_count'] + + info['CN'][self.dataGroup][self.channelGroup][self.channelNumber]['cn_bit_offset'], + self.isnumeric(info)) endian, data_type = data_type_format4(signal_data_type, n_bytes) return '{}{}{}'.format(endian, ca['PNd'], data_type) elif self.type == 3: # CAN channel @@ -879,7 +876,7 @@ def has_invalid_bit(self, info): return True else: return False - + def change_channel_name(self, channel_group): """ In case of duplicate channel names within several channel groups for unsorted data, rename channel name diff --git a/mdfreader/mdf3reader.py b/mdfreader/mdf3reader.py index 45565a6..2abc09c 100644 --- a/mdfreader/mdf3reader.py +++ b/mdfreader/mdf3reader.py @@ -1238,7 +1238,7 @@ def write_pointer(f, pointer, value): else: master_flag = 1 # master channel desc = self.get_channel_desc(channel) - #if bitOffset exceeds two byte limit, we start using the byte offset field + # if bitOffset exceeds two bytes limit, we start using the byte offset field if bit_offset > 0xFFFF: bit_offset -= 0x10000 byte_offset += 8192 diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index 6abb4ac..dd45e4f 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -707,7 +707,7 @@ def load_info(self, info): prev_chan_byte_offset = prev_chan.byteOffset prev_chan_n_bytes = prev_chan.nBytes prev_chan_includes_curr_chan = channel_pos_bit_beg >= 8 * prev_chan_byte_offset \ - and channel_pos_bit_end <= 8 * (prev_chan_byte_offset + prev_chan_n_bytes) + and channel_pos_bit_end <= 8 * (prev_chan_byte_offset + prev_chan_n_bytes) if embedding_channel is not None: embedding_channel_includes_curr_chan = \ channel_pos_bit_end <= embedding_channel.pos_byte_end(info) * 8 @@ -728,7 +728,7 @@ def load_info(self, info): if self.recordToChannelMatching: # not first channel self.recordToChannelMatching[channel.name] = \ self.recordToChannelMatching[prev_chan.name] - else: # first channels + else: # first channels self.recordToChannelMatching[channel.name] = channel.name self.numpyDataRecordFormat.append(data_format) self.dataRecordName.append(channel.name) @@ -953,7 +953,7 @@ def initialise_recarray(self, info, channel_set, n_records, dtype=None, channels def read_channels_from_bytes(self, bit_stream, info, channel_set=None, n_records=None, dtype=None, channels_indexes=None): """ reads stream of record bytes using dataRead module if available otherwise bitarray - + Parameters ------------ bit_stream : stream @@ -965,7 +965,7 @@ def read_channels_from_bytes(self, bit_stream, info, channel_set=None, n_records number of records dtype: numpy dtype channels_indexes: list of int - + Returns -------- rec : numpy recarray @@ -2002,17 +2002,16 @@ def _value_to_text_conversion(vector, cc_val, cc_ref): if isinstance(cc_ref[ref], CCBlock): if cc_ref[ref]['cc_type'] == 3: # formula to be applied - cc_ref[ref] = lambdify(X, cc_ref[ref]['cc_ref']['Comment'] - , modules='numpy', dummify=False) - elif cc_ref[ref]['cc_type'] == 1: # linear conversion - cc_ref[ref] = lambdify(X, '{0}* X + {1}'.format(cc_ref[ref]['cc_val'][1], cc_ref[ref]['cc_val'][0]) - , modules='numpy', dummify=False) + cc_ref[ref] = lambdify(X, cc_ref[ref]['cc_ref']['Comment'], + modules='numpy', dummify=False) + elif cc_ref[ref]['cc_type'] == 1: # linear conversion + cc_ref[ref] = lambdify(X, '{0}* X + {1}'.format(cc_ref[ref]['cc_val'][1], cc_ref[ref]['cc_val'][0]), + modules='numpy', dummify=False) else: warn('To implement missing conversion, please ask') elif (PythonVersion > 3 and not isinstance(cc_ref[ref], str)) or \ (PythonVersion < 3 and not isinstance(cc_ref[ref], unicode)): # identity, non conversion - cc_ref[ref] = lambdify(X, 'X' - , modules='numpy', dummify=False) + cc_ref[ref] = lambdify(X, 'X', modules='numpy', dummify=False) key_index = where(vector[0] == cc_val)[0] # look up for first value in vector if not len(key_index) == 0: # value corresponding in cc_val temp[0] = cc_ref[key_index[0]] @@ -2063,14 +2062,14 @@ def _value_range_to_text_conversion(vector, cc_val, cc_ref): if isinstance(cc_ref[ref], CCBlock): if cc_ref[ref]['cc_type'] == 3: # formula to be applied - cc_ref[ref] = lambdify(X, cc_ref[ref]['cc_ref']['Comment'] - , modules='numpy', dummify=False) + cc_ref[ref] = lambdify(X, cc_ref[ref]['cc_ref']['Comment'], + modules='numpy', dummify=False) elif cc_ref[ref]['cc_type'] == 1: # linear conversion - cc_ref[ref] = lambdify(X, '{0} * X + {1}'.format(cc_val[1], cc_val[0]) - , modules='numpy', dummify=False) + cc_ref[ref] = lambdify(X, '{0} * X + {1}'.format(cc_val[1], cc_val[0]), + modules='numpy', dummify=False) else: # identity, no conversion - cc_ref[ref] = lambdify(X, '1 * X' - , modules='numpy', dummify=False) + cc_ref[ref] = lambdify(X, '1 * X', + modules='numpy', dummify=False) # Otherwise a string # look up in range keys temp = [] diff --git a/mdfreader/mdfinfo3.py b/mdfreader/mdfinfo3.py index 73e892d..c26ffd4 100644 --- a/mdfreader/mdfinfo3.py +++ b/mdfreader/mdfinfo3.py @@ -51,7 +51,7 @@ class Info3(dict): flag to filter long channel names including module names separated by a '.' fileName : str name of file - fid : + fid : file identifier Notes diff --git a/mdfreader/mdfinfo4.py b/mdfreader/mdfinfo4.py index 4b7c82d..c0aa98b 100644 --- a/mdfreader/mdfinfo4.py +++ b/mdfreader/mdfinfo4.py @@ -64,7 +64,7 @@ si_bus_type = {0: 'NONE', 1: 'OTHER', 2: 'CAN', 3: 'LIN', 4: 'MOST', 5: 'FLEXRAY', 6: 'K_LINE', 7: 'ETHERNET', 8: 'USB'} # EV cause -ev_cause = {0: 'OTHER',1: 'ERROR', 2: 'TOOL', 3: 'SCRIPT', 4: 'USER'} +ev_cause = {0: 'OTHER', 1: 'ERROR', 2: 'TOOL', 3: 'SCRIPT', 4: 'USER'} # precompiled path for xmls to speed up parsing CN_TX = objectify.ObjectPath('CNcomment.TX') diff --git a/mdfreader/mdfreader.py b/mdfreader/mdfreader.py index 34b5898..499fd2b 100644 --- a/mdfreader/mdfreader.py +++ b/mdfreader/mdfreader.py @@ -122,7 +122,7 @@ class MdfInfo(dict): fid file identifier zipfile - flag to indicate the mdf4 is packaged in a zip + flag to indicate the mdf4 is packaged in a zip Methods ------------ @@ -224,7 +224,7 @@ def list_channels(self, file_name=None): else: channel_name_list = Info4() name_list = channel_name_list.list_channels_4(self.fileName, self.fid) - if zipfile: # not from mdfreader.read() + if zipfile: # not from mdfreader.read() remove(self.fileName) return name_list @@ -625,7 +625,7 @@ def interpolate(new_x, x, y): unit=self.get_channel_unit(master), description=self.get_channel_desc(master), conversion=None) else: - master_channel_name = master_channel # master channel defined in argument + master_channel_name = master_channel # master channel defined in argument if master_channel not in list(self.masterChannelList.keys()): warn('master channel name not in existing') raise ValueError('Master Channel not existing') @@ -726,7 +726,7 @@ def cut(self, begin=None, end=None): if begin is None and end is None: raise Exception('Please input at least one beginning or ending value to cut data') - for master in self.masterChannelList: # for each channel group + for master in self.masterChannelList: # for each channel group # find corresponding indexes to cut master_data = self.get_channel_data(master) if master_data is not None and len(master_data) > 0: # not empty data @@ -764,7 +764,7 @@ def export_to_csv(self, file_name=None, sampling=None): data not sharing same master channel Warning: this can be slow for big data, CSV is text format after all """ - if self: # data in mdf + if self: # data in mdf import csv self.resample(sampling) if file_name is None: @@ -1070,7 +1070,7 @@ def export_to_matlab(self, file_name=None): data = self.get_channel_data(channel) if data.dtype.kind not in ('S', 'U', 'V'): # does not like special characters chains, skip channel_name = _convert_to_matlab_name(channel) - if len(channel_name) > 0 and channel_name is not None: + if len(channel_name) > 0 and channel_name is not None: temp[channel_name] = data elif channel_name is not None: warn(u'Could not export {}, name is not compatible with Matlab'.format(channel)) From 19309caea3fd21ccccddd994590341d0118610b8 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Sun, 4 Nov 2018 20:41:19 +0100 Subject: [PATCH 51/61] refactored comment block for more granularity and performance of execution --- mdfreader/mdfinfo4.py | 598 +++++++++++++++++++++++++++++------------- 1 file changed, 415 insertions(+), 183 deletions(-) diff --git a/mdfreader/mdfinfo4.py b/mdfreader/mdfinfo4.py index c0aa98b..e356827 100644 --- a/mdfreader/mdfinfo4.py +++ b/mdfreader/mdfinfo4.py @@ -252,7 +252,7 @@ def read(self, fid=None): if self['hd_md_comment']: # if comments exist self['Comment'] = {} comment = CommentBlock() - comment.read_cm(fid=fid, pointer=self['hd_md_comment'], MDType=3) + comment.read_cm_hd(fid=fid, pointer=self['hd_md_comment']) self['Comment'].update(comment) def write(self, fid): @@ -299,7 +299,7 @@ def read(self, fid, pointer): if self['fh_md_comment']: # comments exist self['Comment'] = {} comment = CommentBlock() - comment.read_cm(fid=fid, pointer=self['fh_md_comment'], MDType=4) + comment.read_cm_fh(fid=fid, pointer=self['fh_md_comment']) self['Comment'].update(comment) def write(self, fid): @@ -340,12 +340,12 @@ def __init__(self, fid, pointer): if self['ch_md_comment']: # comments exist self['Comment'] = {} comment = CommentBlock() - comment.read_cm(fid=fid, pointer=self['ch_md_comment']) + comment.read_cm_ch(fid=fid, pointer=self['ch_md_comment']) self['Comment'].update(comment) if self['ch_tx_name']: # text block containing name of hierarchy level self['ch_name_level'] = {} comment = CommentBlock() - comment.read_cm(fid=fid, pointer=self['ch_tx_name']) + comment.read_tx(fid=fid, pointer=self['ch_tx_name']) self['ch_name_level'].update(comment) @@ -353,8 +353,8 @@ class CommentBlock(dict): """ reads or writes Comment block and saves in class dict """ - def read_cm(self, **kargs): - """ reads Comment block and saves in class dict + def read_tx(self, fid, pointer): + """ reads TX block Parameters ---------- @@ -362,195 +362,427 @@ def read_cm(self, **kargs): file identifier pointer: int position in file - MDType: str - describes metadata type, ('CN', 'unit', 'FH', 'SI', 'HD', 'CC', 'EV') - - Notes - -------- - Can read xml (MD metadata) or text (TX) comments from several - kind of blocks """ + if pointer > 0: + fid.seek(pointer) + # block header + (self['id'], + reserved, + self['length'], + self['link_count']) = _HeaderStruct.unpack(fid.read(24)) + self['Comment'] = fid.read(self['length'] - 24).rstrip(b'\x00').decode('UTF-8', 'ignore') - if kargs['pointer'] > 0: - kargs['fid'].seek(kargs['pointer']) + def read_cm_header(self, fid, pointer): + """ reads Comment block header + + Parameters + ---------- + fid: + file identifier + pointer: int + position in file + """ + if pointer > 0: + fid.seek(pointer) # block header (self['id'], reserved, self['length'], - self['link_count']) = _HeaderStruct.unpack(kargs['fid'].read(24)) + self['link_count']) = _HeaderStruct.unpack(fid.read(24)) + + def read_xml(self, fid): + """ reads Comment block xml and objectifies it + + Parameters + ---------- + fid: + file identifier + """ + # Metadata block + # removes normal 0 at end + try: + xml_string = fid.read(self['length'] - 24).rstrip(b'\x00') + xml_tree = objectify.fromstring(xml_string) + except: + warn('xml metadata malformed') + xml_tree = None + return xml_tree + + def read_cm_hd(self, fid, pointer): + """ reads Comment block from header block + + Parameters + ---------- + fid: + file identifier + pointer: int + position in file + """ + if pointer > 0: + self.read_cm_header(fid, pointer) if self['id'] in ('##MD', b'##MD'): - # Metadata block - # removes normal 0 at end - # self['Comment'] = None + xml_tree = self.read_xml(fid) try: - xml_string = kargs['fid'].read(self['length'] - 24).rstrip(b'\x00') - xml_tree = objectify.fromstring(xml_string) - except: - warn('xml metadata malformed') - xml_tree = None - # specific action per comment block type, - # #extracts specific tags from xml - if 'MDType' in kargs: - if kargs['MDType'] == 0: # channel comment - try: - self['description'] = CN_TX(xml_tree).text - except AttributeError: - warn('Could not parse CN block TX tag') - try: - self['names'] = CN_names(xml_tree).text - except AttributeError: - pass # optional - if 'minimal' in kargs and kargs['minimal'] is False: - # not really used for the moment - try: - self['axis_monotony'] = CN_axis_monotony(xml_tree).text - except AttributeError: - pass # optional - try: - self['raster'] = CN_raster(xml_tree).text - except AttributeError: - pass # optional - try: - self['formula'] = CN_formula(xml_tree).text - except AttributeError: - pass # optional - try: - self['linker_name'] = CN_linker_name(xml_tree).text - except AttributeError: - pass # optional - try: - self['linker_address'] = CN_linker_address(xml_tree).text - except AttributeError: - pass # optional - try: - self['address'] = CN_address(xml_tree).text - except AttributeError: - pass # optional - elif kargs['MDType'] == 1: # cn_unit channel unit - try: - self['unit'] = CN_unit_TX(xml_tree).text - except AttributeError: - warn('Could not parse unit TX tag') - elif kargs['MDType'] == 2: # CC channel unit - try: - self['unit'] = CC_unit_TX(xml_tree).text - except AttributeError: - warn('Could not parse unit TX tag') - elif kargs['MDType'] == 5: # SI comments - try: - self['TX'] = SI_TX(xml_tree).text - except AttributeError: - warn('Could not parse SI block TX tag') - try: - self['names'] = SI_names(xml_tree).text - except AttributeError: - pass # optional - try: - self['path'] = SI_path(xml_tree).text - except AttributeError: - pass # optional - try: - self['bus'] = SI_bus(xml_tree).text - except AttributeError: - pass # optional - try: - self['protocol'] = SI_protocol(xml_tree).text - except AttributeError: - pass # optional - elif kargs['MDType'] == 3: # HD header comment - try: - self['TX'] = xml_tree.TX.text - except AttributeError: - warn('Could not parse HD block TX tag') - try: - self['time_source'] = xml_tree.time_source.text - except AttributeError: - pass # optional - try: - tmp = xml_tree.common_properties - for t in range(tmp.countchildren()): - self[tmp.e[t].attrib.values()[0]] = tmp.e[t].text - except AttributeError: - pass # optional - elif kargs['MDType'] == 4: # FH file History comment - try: - self['TX'] = xml_tree.TX.text - except AttributeError: - warn('Could not parse FH block TX tag') - try: - self['tool_id'] = xml_tree.tool_id.text - except AttributeError: - warn('Could not parse FH block tool_id tag') - try: - self['tool_vendor'] = xml_tree.tool_vendor.text - except AttributeError: - warn('Could not parse extract HD block tool_vendor tag') - try: - self['tool_version'] = xml_tree.tool_version.text - except AttributeError: - warn('Could not parse extract HD block tool_vendor tag') - try: - self['user_name'] = xml_tree.user_name.text - except AttributeError: - pass # optional - elif kargs['MDType'] == 6: # CC comments - try: - self['TX'] = CC_TX(xml_tree).text - except AttributeError: - warn('Could not parse CC block TX tag') - try: - self['names'] = CC_names(xml_tree).text - except AttributeError: - pass # optional + self['TX'] = xml_tree.TX.text + except AttributeError: + warn('Could not parse HD block TX tag') + try: + self['time_source'] = xml_tree.time_source.text + except AttributeError: + pass # optional + try: + tmp = xml_tree.common_properties + for t in range(tmp.countchildren()): + self[tmp.e[t].attrib.values()[0]] = tmp.e[t].text + except AttributeError: + pass # optional + elif self['id'] in ('##TX', b'##TX'): + self['Comment'] = fid.read(self['length'] - 24).rstrip(b'\x00').decode('UTF-8', 'ignore') + + def read_cm_fh(self, fid, pointer): + """ reads Comment block from file history block + + Parameters + ---------- + fid: + file identifier + pointer: int + position in file + """ + if pointer > 0: + self.read_cm_header(fid, pointer) + if self['id'] in ('##MD', b'##MD'): + xml_tree = self.read_xml(fid) + try: + self['TX'] = xml_tree.TX.text + except AttributeError: + warn('Could not parse FH block TX tag') + try: + self['tool_id'] = xml_tree.tool_id.text + except AttributeError: + warn('Could not parse FH block tool_id tag') + try: + self['tool_vendor'] = xml_tree.tool_vendor.text + except AttributeError: + warn('Could not parse extract HD block tool_vendor tag') + try: + self['tool_version'] = xml_tree.tool_version.text + except AttributeError: + warn('Could not parse extract HD block tool_vendor tag') + try: + self['user_name'] = xml_tree.user_name.text + except AttributeError: + pass # optional + elif self['id'] in ('##TX', b'##TX'): + self['Comment'] = fid.read(self['length'] - 24).rstrip(b'\x00').decode('UTF-8', 'ignore') + + def read_cm_ch(self, fid, pointer): + """ reads Comment block from file channel hierarchy block + + Parameters + ---------- + fid: + file identifier + pointer: int + position in file + """ + if pointer > 0: + self.read_cm_header(fid, pointer) + if self['id'] in ('##MD', b'##MD'): + xml_tree = self.read_xml(fid) + if xml_tree is not None: + try: + self['TX'] = xml_tree.TX.text + except AttributeError: + warn('Could not parse CH block TX tag') + try: + self['names'] = xml_tree.names.text + except AttributeError: + warn('Could not parse CH block names tag') + elif self['id'] in ('##TX', b'##TX'): + self['Comment'] = fid.read(self['length'] - 24).rstrip(b'\x00').decode('UTF-8', 'ignore') + + def read_cm_at(self, fid, pointer): + """ reads Comment block from attachment block + + Parameters + ---------- + fid: + file identifier + pointer: int + position in file + """ + if pointer > 0: + self.read_cm_header(fid, pointer) + xml_tree = self.read_xml(fid) + try: + self['TX'] = xml_tree.TX.text + except AttributeError: + warn('Could not parse AT block TX tag') + + def read_cm_ev(self, fid, pointer): + """ reads Comment block from event block + + Parameters + ---------- + fid: + file identifier + pointer: int + position in file + """ + if pointer > 0: + self.read_cm_header(fid, pointer) + if self['id'] in ('##MD', b'##MD'): + xml_tree = self.read_xml(fid) + if xml_tree is not None: + try: + self['TX'] = EV_TX(xml_tree).text + except AttributeError: + warn('Could not parse EV block TX tag') + try: + self['pre_trigger_interval'] = EV_pre_trigger_interval(xml_tree).text + except AttributeError: + pass # optional + try: + self['post_trigger_interval'] = EV_post_trigger_interval(xml_tree).text + except AttributeError: + pass # optional + try: + self['formula'] = EV_formula(xml_tree).text + except AttributeError: + pass # optional + try: + self['timeout'] = EV_timeout(xml_tree).text + except AttributeError: + pass # optional + elif self['id'] in ('##TX', b'##TX'): + self['Comment'] = fid.read(self['length'] - 24).rstrip(b'\x00').decode('UTF-8', 'ignore') + + def read_cm_dg(self, fid, pointer): + """ reads Comment block from data group block + + Parameters + ---------- + fid: + file identifier + pointer: int + position in file + """ + if pointer > 0: + self.read_cm_header(fid, pointer) + if self['id'] in ('##MD', b'##MD'): + xml_tree = self.read_xml(fid) + try: + self['TX'] = xml_tree.TX.text + except AttributeError: + warn('Could not parse AT block TX tag') + elif self['id'] in ('##TX', b'##TX'): + self['Comment'] = fid.read(self['length'] - 24).rstrip(b'\x00').decode('UTF-8', 'ignore') + + def read_cm_cg(self, fid, pointer): + """ reads Comment block from channel group block + + Parameters + ---------- + fid: + file identifier + pointer: int + position in file + """ + if pointer > 0: + self.read_cm_header(fid, pointer) + if self['id'] in ('##MD', b'##MD'): + xml_tree = self.read_xml(fid) + try: + self['TX'] = xml_tree.TX.text + except AttributeError: + warn('Could not parse CG block TX tag') + try: + self['names'] = xml_tree.names.text + except AttributeError: + warn('Could not parse CG block names tag') + elif self['id'] in ('##TX', b'##TX'): + self['Comment'] = fid.read(self['length'] - 24).rstrip(b'\x00').decode('UTF-8', 'ignore') + + def read_cm_si(self, fid, pointer): + """ reads Comment block from source information block + + Parameters + ---------- + fid: + file identifier + pointer: int + position in file + """ + if pointer > 0: + self.read_cm_header(fid, pointer) + if self['id'] in ('##MD', b'##MD'): + xml_tree = self.read_xml(fid) + if xml_tree is not None: + try: + self['TX'] = SI_TX(xml_tree).text + except AttributeError: + warn('Could not parse SI block TX tag') + try: + self['names'] = SI_names(xml_tree).text + except AttributeError: + pass # optional + try: + self['path'] = SI_path(xml_tree).text + except AttributeError: + pass # optional + try: + self['bus'] = SI_bus(xml_tree).text + except AttributeError: + pass # optional + try: + self['protocol'] = SI_protocol(xml_tree).text + except AttributeError: + pass # optional + elif self['id'] in ('##TX', b'##TX'): + self['Comment'] = fid.read(self['length'] - 24).rstrip(b'\x00').decode('UTF-8', 'ignore') + + def read_cm_cn(self, fid, pointer, minimal=True): + """ reads Comment block from channel block + + Parameters + ---------- + fid: + file identifier + pointer: int + position in file + minimal: boolean + flag to reduce metadata parsing + """ + if pointer > 0: + self.read_cm_header(fid, pointer) + if self['id'] in ('##MD', b'##MD'): + xml_tree = self.read_xml(fid) + if xml_tree is not None: + try: + self['description'] = CN_TX(xml_tree).text + except AttributeError: + warn('Could not parse CN block TX tag') + try: + self['names'] = CN_names(xml_tree).text + except AttributeError: + pass # optional + if minimal is False: + # not really used for the moment try: - self['COMPU_METHOD'] = CC_COMPU_METHOD(xml_tree).text + self['axis_monotony'] = CN_axis_monotony(xml_tree).text except AttributeError: pass # optional try: - self['formula'] = CC_formula(xml_tree).text + self['raster'] = CN_raster(xml_tree).text except AttributeError: pass # optional - elif kargs['MDType'] == 7: # EV comments - try: - self['TX'] = EV_TX(xml_tree).text - except AttributeError: - warn('Could not parse EV block TX tag') try: - self['pre_trigger_interval'] = EV_pre_trigger_interval(xml_tree).text + self['formula'] = CN_formula(xml_tree).text except AttributeError: pass # optional try: - self['post_trigger_interval'] = EV_post_trigger_interval(xml_tree).text + self['linker_name'] = CN_linker_name(xml_tree).text except AttributeError: pass # optional try: - self['formula'] = EV_formula(xml_tree).text + self['linker_address'] = CN_linker_address(xml_tree).text except AttributeError: pass # optional try: - self['timeout'] = EV_timeout(xml_tree).text + self['address'] = CN_address(xml_tree).text except AttributeError: pass # optional - else: - if kargs['MDType'] is not None: - warn('No recognized MDType {}'.format(kargs['MDType'])) elif self['id'] in ('##TX', b'##TX'): - if 'MDType' in kargs and kargs['MDType'] == 0: # channel comment - self['name'] = kargs['fid'].read(self['length'] - 24).rstrip(b'\x00').decode('UTF-8', 'ignore') - else: - self['Comment'] = kargs['fid'].read(self['length'] - 24).rstrip(b'\x00').decode('UTF-8', 'ignore') + self['name'] = fid.read(self['length'] - 24).rstrip(b'\x00').decode('UTF-8', 'ignore') + + def read_cm_cn_unit(self, fid, pointer): + """ reads Comment block for channel unit + + Parameters + ---------- + fid: + file identifier + pointer: int + position in file + """ + if pointer > 0: + self.read_cm_header(fid, pointer) + if self['id'] in ('##MD', b'##MD'): + xml_tree = self.read_xml(fid) + try: + self['unit'] = CN_unit_TX(xml_tree).text + except AttributeError: + warn('Could not parse unit TX tag') + elif self['id'] in ('##TX', b'##TX'): + self['Comment'] = fid.read(self['length'] - 24).rstrip(b'\x00').decode('UTF-8', 'ignore') + + def read_cm_cc(self, fid, pointer): + """ reads Comment block from channel conversion block + + Parameters + ---------- + fid: + file identifier + pointer: int + position in file + """ + if pointer > 0: + self.read_cm_header(fid, pointer) + if self['id'] in ('##MD', b'##MD'): + xml_tree = self.read_xml(fid) + if xml_tree is not None: + try: + self['TX'] = CC_TX(xml_tree).text + except AttributeError: + warn('Could not parse CC block TX tag') + try: + self['names'] = CC_names(xml_tree).text + except AttributeError: + pass # optional + try: + self['COMPU_METHOD'] = CC_COMPU_METHOD(xml_tree).text + except AttributeError: + pass # optional + try: + self['formula'] = CC_formula(xml_tree).text + except AttributeError: + pass # optional + elif self['id'] in ('##TX', b'##TX'): + self['Comment'] = fid.read(self['length'] - 24).rstrip(b'\x00').decode('UTF-8', 'ignore') + + def read_cm_cc_unit(self, fid, pointer): + """ reads Comment block for channel conversion unit + + Parameters + ---------- + fid: + file identifier + pointer: int + position in file + """ + if pointer > 0: + self.read_cm_header(fid, pointer) + if self['id'] in ('##MD', b'##MD'): + xml_tree = self.read_xml(fid) + try: + self['unit'] = CC_unit_TX(xml_tree).text + except AttributeError: + warn('Could not parse unit TX tag') + elif self['id'] in ('##TX', b'##TX'): + self['Comment'] = fid.read(self['length'] - 24).rstrip(b'\x00').decode('UTF-8', 'ignore') - def load(self, data, MDType): - if MDType == 'TX': + def load(self, data, md_type): + if md_type == 'TX': data = b''.join([data.encode('utf-8', 'replace'), b'\0']) block_id = b'##TX' else: register_namespace('', 'http://www.asam.net/mdf/v4') - if MDType == 'HD': + if md_type == 'HD': root = Element('HDcomment') root.set('xmlns', 'http://www.asam.net/mdf/v4') - TX = SubElement(root, 'TX') - TX.text = data['comment'] + tx = SubElement(root, 'TX') + tx.text = data['comment'] common_properties = SubElement(root, 'common_properties') e = SubElement(common_properties, 'e', attrib={'name': 'subject'}) @@ -564,13 +796,13 @@ def load(self, data, MDType): e = SubElement(common_properties, 'e', attrib={'name': 'author'}) e.text = data['author'] - elif MDType == 'CN': + elif md_type == 'CN': pass - elif MDType == 'FH': + elif md_type == 'FH': root = Element('FHcomment') root.set('xmlns', 'http://www.asam.net/mdf/v4') - TX = SubElement(root, 'TX') - TX.text = data['comment'] + tx = SubElement(root, 'TX') + tx.text = data['comment'] tool_id = SubElement(root, 'tool_id') tool_id.text = 'mdfreader' tool_vendor = SubElement(root, 'tool_vendor') @@ -617,7 +849,7 @@ def read(self, fid, pointer): if self['dg_md_comment']: # comments exist self['Comment'] = {} comment = CommentBlock() - comment.read_cm(fid=fid, pointer=self['dg_md_comment']) + comment.read_cm_dg(fid=fid, pointer=self['dg_md_comment']) self['Comment'].update(comment) def write(self, fid): @@ -664,11 +896,11 @@ def read(self, fid, pointer): self['cg_invalid_bytes']) = _CGStruct.unpack(fid.read(104)) if self['cg_md_comment']: # comments exist self['Comment'] = CommentBlock() - self['Comment'].read_cm(fid=fid, pointer=self['cg_md_comment']) + self['Comment'].read_cm_cg(fid=fid, pointer=self['cg_md_comment']) if self['cg_tx_acq_name']: # comments exist self['acq_name'] = {} comment = CommentBlock() - comment.read_cm(fid=fid, pointer=self['cg_tx_acq_name']) + comment.read_tx(fid=fid, pointer=self['cg_tx_acq_name']) self['acq_name'].update(comment) if self['cg_si_acq_source']: # comments exist self['acq_source'] = {} @@ -754,10 +986,10 @@ def read_cn(self, **kargs): self['cn_default_x'] = None if self['cn_md_comment']: # comments exist self['Comment'] = CommentBlock() - self['Comment'].read_cm(fid=kargs['fid'], pointer=self['cn_md_comment'], MDType=0, minimal=True) + self['Comment'].read_cm_cn(fid=kargs['fid'], pointer=self['cn_md_comment'], minimal=True) if self['cn_md_unit']: # comments exist self['unit'] = CommentBlock() - self['unit'].read_cm(fid=kargs['fid'], pointer=self['cn_md_unit'], MDType=1) + self['unit'].read_cm_cn_unit(fid=kargs['fid'], pointer=self['cn_md_unit']) if self['cn_sync_type'] and (self['unit'] is None or not self['unit']): # no units but already known by spec if self['cn_sync_type'] == 1: @@ -768,8 +1000,8 @@ def read_cn(self, **kargs): self['unit'] = 'm' if self['cn_tx_name']: # comments exist comment = CommentBlock() - comment.read_cm(fid=kargs['fid'], pointer=self['cn_tx_name'], MDType=0) - self['name'] = comment['name'] + comment.read_tx(fid=kargs['fid'], pointer=self['cn_tx_name']) + self['name'] = comment['Comment'] def write(self, fid): # write block header @@ -832,7 +1064,7 @@ def read_cc(self, fid, pointer): pointer = self['cc_ref'] self['cc_ref'] = {} cc = CommentBlock() - cc.read_cm(fid=fid, pointer=pointer) + cc.read_tx(fid=fid, pointer=pointer) self['cc_ref'].update(cc) elif self['cc_type']in (7, 8, 9, 10): # text list self['cc_ref'] = list(self['cc_ref']) @@ -843,7 +1075,7 @@ def read_cc(self, fid, pointer): # for algebraic formulae if identifier in ('##TX', '##MD', b'##TX', b'##MD'): temp = CommentBlock() - temp.read_cm(fid=fid, pointer=self['cc_ref'][i]) + temp.read_tx(fid=fid, pointer=self['cc_ref'][i]) self['cc_ref'][i] = temp['Comment'] elif identifier in ('##CC', b'##CC'): # for table conversion # much more complicated nesting conversions !!! @@ -852,13 +1084,13 @@ def read_cc(self, fid, pointer): self['cc_ref'][i] = cc if self['cc_md_comment']: # comments exist self['Comment'] = CommentBlock() - self['Comment'].read_cm(fid=fid, pointer=self['cc_md_comment'], MDType=6) + self['Comment'].read_cm_cc(fid=fid, pointer=self['cc_md_comment']) if self['cc_md_unit']: # comments exist self['unit'] = CommentBlock() - self['unit'].read_cm(fid=fid, pointer=self['cc_md_unit'], MDType=2) + self['unit'].read_cm_cc_unit(fid=fid, pointer=self['cc_md_unit']) if self['cc_tx_name']: # comments exist self['name'] = CommentBlock() - self['name'].read_cm(fid=fid, pointer=self['cc_tx_name']) + self['name'].read_tx(fid=fid, pointer=self['cc_tx_name']) else: # no conversion self['cc_type'] = 0 @@ -970,7 +1202,7 @@ def __init__(self, fid, pointer): if self['at_md_comment']: # comments exist self['Comment'] = {} comment = CommentBlock() - comment.read_cm(fid=fid, pointer=self['at_md_comment']) + comment.read_cm_at(fid=fid, pointer=self['at_md_comment']) self['Comment'].update(comment) @@ -1021,10 +1253,10 @@ def __init__(self, fid, pointer): ATBlock(fid, self['ev_at_reference'][at]) if self['ev_md_comment']: # comments exist self['Comment'] = CommentBlock() - self['Comment'].read_cm(fid=fid, pointer=self['ev_md_comment'], MDType=7) + self['Comment'].read_cm_ev(fid=fid, pointer=self['ev_md_comment']) if self['ev_tx_name']: # comments exist self['name'] = CommentBlock() - self['name'].read_cm(fid=fid, pointer=self['ev_tx_name']) + self['name'].read_tx(fid=fid, pointer=self['ev_tx_name']) class SRBlock(dict): @@ -1079,11 +1311,11 @@ def read_si(self, fid, pointer): warn('unexpected SI bus type') # post treatment self['source_name'] = CommentBlock() - self['source_name'].read_cm(fid=fid, pointer=self['si_tx_name']) + self['source_name'].read_tx(fid=fid, pointer=self['si_tx_name']) self['source_path'] = CommentBlock() - self['source_path'].read_cm(fid=fid, pointer=self['si_tx_path']) + self['source_path'].read_tx(fid=fid, pointer=self['si_tx_path']) self['comment'] = CommentBlock() - self['comment'].read_cm(fid=fid, pointer=self['si_md_comment'], MDType=5) + self['comment'].read_cm_si(fid=fid, pointer=self['si_md_comment']) class DTBlock(dict): From 55f0383c5be0d1302b1f7f3c40e22fd6daa84c64 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Tue, 6 Nov 2018 22:29:22 +0100 Subject: [PATCH 52/61] More pep8 and docs improvements --- README.md | 2 +- docs/mdfreader.pdf | Bin 222711 -> 225475 bytes mdfreader/mdf.py | 4 ++-- mdfreader/mdf3reader.py | 2 +- mdfreader/mdf4reader.py | 4 ++-- mdfreader/mdfinfo4.py | 2 +- mdfreader/mdfreader.py | 4 ++-- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 12ee30a..0c96e31 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ Command example in ipython: # You can reduce to minimum metadata reading with below argument (no source information, attachment, etc.) yop=mdfreader.Mdf('NameOfFile', metadata=0) # 0: full, 2: minimal # only for mdf4.x, you can search for the mdf key of a channel name that can have been recorded by different sources - yop.get_channel_name_4('channelName', 'source path or name') # returns list of mdf keys + yop.get_channel_name4('channelName', 'source path or name') # returns list of mdf keys # to yield one channel and keep its content in mdf object yop.get_channel('channelName') # to yield one channel numpy array diff --git a/docs/mdfreader.pdf b/docs/mdfreader.pdf index a6ce123928b6b738e9d6a09677acd9c97588e56b..17a21a53d7019824a82e59656344fd92035b32e2 100644 GIT binary patch delta 68550 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 e3-`9)ui292kAh%+dyj(rK*Y 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 delta 65859 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 Kq%b(<01vZiY{R(qcf4z=zMtdARNbNM(B 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%0D~cD=n<9JgE8_RLxy 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 z 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 diff --git a/mdfreader/mdf.py b/mdfreader/mdf.py index b8b2858..1476c29 100644 --- a/mdfreader/mdf.py +++ b/mdfreader/mdf.py @@ -55,7 +55,7 @@ class MdfSkeleton(dict): __slots__ = ['masterChannelList', 'fileName', 'MDFVersionNumber', 'multiProc', - 'convertAfterRead', 'filterChannelNames', 'file_metadata', 'convert_tables', + 'convertAfterRead', 'filterChannelNames', 'fileMetadata', 'convertTables', '_pandasframe', 'info', '_compression_level', '_noDataLoading', 'fid', 'zipfile'] """ MdfSkeleton class @@ -76,7 +76,7 @@ class MdfSkeleton(dict): flag to convert raw data to physical just after read filterChannelNames : bool flag to filter long channel names from its module names separated by '.' - file_metadata : dict + fileMetadata : dict file metadata with minimum keys : author, organisation, project, subject, comment, time, date Methods diff --git a/mdfreader/mdf3reader.py b/mdfreader/mdf3reader.py index 2abc09c..3b17199 100644 --- a/mdfreader/mdf3reader.py +++ b/mdfreader/mdf3reader.py @@ -795,7 +795,7 @@ class Mdf3(MdfSkeleton): flag to convert raw data to physical just after read filterChannelNames : bool flag to filter long channel names from its module names separated by '.' - file_metadata : dict + fileMetadata : dict file metadata with minimum keys: author, organisation, project, subject, comment, time, date Methods diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index dd45e4f..2384890 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -1117,7 +1117,7 @@ class Mdf4(MdfSkeleton): flag to convert raw data to physical just after read filterChannelNames : bool flag to filter long channel names from its module names separated by '.' - file_metadata : dict + fileMetadata : dict file metadata with minimum keys : author, organisation, project, subject, comment, time, date Methods @@ -1808,7 +1808,7 @@ def apply_invalid_bit(self, channel_name): pass # warn('no invalid data found for channel ') - def get_channel_name_4(self, name, path): + def get_channel_name4(self, name, path): """finds mdf channel name from name and path Parameters diff --git a/mdfreader/mdfinfo4.py b/mdfreader/mdfinfo4.py index e356827..15652e2 100644 --- a/mdfreader/mdfinfo4.py +++ b/mdfreader/mdfinfo4.py @@ -2038,7 +2038,7 @@ def read_at_block(fid, pointer): at_blocks[at] = (ATBlock(fid, at_blocks[at - 1]['at_at_next'])) return at_blocks - def list_channels_4(self, file_name=None, fid=None): + def list_channels4(self, file_name=None, fid=None): """ Read MDF file and extract its complete structure Parameters diff --git a/mdfreader/mdfreader.py b/mdfreader/mdfreader.py index 499fd2b..e897f72 100644 --- a/mdfreader/mdfreader.py +++ b/mdfreader/mdfreader.py @@ -223,7 +223,7 @@ def list_channels(self, file_name=None): name_list = channel_name_list.list_channels3(self.fileName, self.fid) else: channel_name_list = Info4() - name_list = channel_name_list.list_channels_4(self.fileName, self.fid) + name_list = channel_name_list.list_channels4(self.fileName, self.fid) if zipfile: # not from mdfreader.read() remove(self.fileName) return name_list @@ -258,7 +258,7 @@ class Mdf(Mdf3, Mdf4): multiProc : bool Flag to request channel conversion multi processed for performance improvement. One thread per data group. - file_metadata : dict + fileMetadata : dict file metadata with minimum keys : author, organisation, project, subject, comment, time, date Methods From 53ed9a491e37c3144ea70c64167e937b26ef7f64 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Tue, 6 Nov 2018 22:47:15 +0100 Subject: [PATCH 53/61] Some pep8 refactoring --- mdfreader/mdfinfo3.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mdfreader/mdfinfo3.py b/mdfreader/mdfinfo3.py index c26ffd4..2a392a6 100644 --- a/mdfreader/mdfinfo3.py +++ b/mdfreader/mdfinfo3.py @@ -68,16 +68,16 @@ class Info3(dict): - mdfinfo['CCBlock'][dataGroup][channelGroup][channel] Channel conversion information """ - def __init__(self, fileName=None, fid=None, filterChannelNames=False, minimal=0): + def __init__(self, file_name=None, fid=None, filter_channel_names=False, minimal=0): """ info3 class constructor Parameters ---------------- - fileName : str, optional + file_name : str, optional name of file fid : float, optional file identifier - filterChannelNames : bool, optional + filter_channel_names : bool, optional flag to filter long channel names including module names separated by a '.' minimal : int 0 will load every metadata @@ -96,16 +96,16 @@ def __init__(self, fileName=None, fid=None, filterChannelNames=False, minimal=0) self['CCBlock'] = dict() # Conversion block self['allChannelList'] = set() # all channels self['ChannelNamesByDG'] = dict() - self.filterChannelNames = filterChannelNames - self.fileName = fileName + self.filterChannelNames = filter_channel_names + self.fileName = file_name self.fid = None - if fileName is not None and fid is None: + if file_name is not None and fid is None: try: self.fid = open(self.fileName, 'rb') except IOError: raise IOError('Can not find file ' + self.fileName) self.read_info3(self.fid, minimal) - elif fileName is None and fid is not None: + elif file_name is None and fid is not None: self.read_info3(fid, minimal) def read_info3(self, fid, minimal=0): From d5d577cc32d9151e6c521696030b25101051ff9f Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Tue, 6 Nov 2018 23:41:20 +0100 Subject: [PATCH 54/61] first tentative fix for sd block having type not string but byte array --- mdfreader/mdf4reader.py | 61 +++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index 2384890..357030f 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -217,23 +217,33 @@ def _read_sd_block(signal_data_type, sd_block, sd_block_length): ----------- array """ - if signal_data_type == 6: - channel_format = 'ISO8859' - elif signal_data_type == 7: - channel_format = 'utf-8' - elif signal_data_type == 8: - channel_format = ' Date: Wed, 7 Nov 2018 21:01:06 +0100 Subject: [PATCH 55/61] Fixed bug for sd block and byte array type --- mdfreader/mdf4reader.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index 357030f..16f2569 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -237,6 +237,7 @@ def _read_sd_block(signal_data_type, sd_block, sd_block_length): buf.append(sd_block[pointer:pointer + VLSDLen].decode(channel_format).rstrip('\x00')) pointer += VLSDLen buf = _equalize_string_length(buf) + return array(buf) else: # byte arrays or mime types while pointer < sd_block_length: VLSDLen = structunpack('I', sd_block[pointer:pointer + 4])[0] # length of data @@ -259,8 +260,8 @@ def _equalize_string_length(buf): list of str elements all having same length """ max_len = len(max(buf, key=len)) - for i in range(len(buf)): # resize string to same length, numpy constrain - buf[i] = ''.join([buf[i], ' ' * (max_len - len(buf[i]))]) + for i, element in enumerate(buf): # resize string to same length, numpy constrain + buf[i] = ''.join([element, ' ' * (max_len - len(element))]) return buf @@ -276,8 +277,8 @@ def _equalize_byte_length(buf): list of bytes all having same length """ max_len = len(max(buf, key=len)) - for i in range(len(buf)): # resize string to same length, numpy constrain - buf[i] = buf[i].append('\x00' * (max_len - len(buf[i]))) + for i, element in enumerate(buf): # resize string to same length, numpy constrain + buf[i] = bytearray(element).extend(b'0' * (max_len - len(element))) return buf From 9a0ba54a1ea0c656d91738f3c9eff93a908e880a Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Wed, 7 Nov 2018 21:05:53 +0100 Subject: [PATCH 56/61] Some pep8 refactoring --- mdfreader/mdf3reader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mdfreader/mdf3reader.py b/mdfreader/mdf3reader.py index 3b17199..9e570d8 100644 --- a/mdfreader/mdf3reader.py +++ b/mdfreader/mdf3reader.py @@ -872,7 +872,7 @@ def read3(self, file_name=None, info=None, multi_processed=False, channel_list=N # Read information block from file if info is None: if self.info is None: - info = Info3(self.fileName, fid=None, filterChannelNames=False, minimal=minimal) + info = Info3(self.fileName, fid=None, filter_channel_names=False, minimal=minimal) else: info = self.info From b7ea87ef2e30b19869834a6eed594e4616a4d8f5 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Thu, 8 Nov 2018 21:40:09 +0100 Subject: [PATCH 57/61] fixed issue with sd block and byte array reading --- mdfreader/mdf4reader.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index 16f2569..ef11604 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -237,14 +237,13 @@ def _read_sd_block(signal_data_type, sd_block, sd_block_length): buf.append(sd_block[pointer:pointer + VLSDLen].decode(channel_format).rstrip('\x00')) pointer += VLSDLen buf = _equalize_string_length(buf) - return array(buf) else: # byte arrays or mime types while pointer < sd_block_length: VLSDLen = structunpack('I', sd_block[pointer:pointer + 4])[0] # length of data pointer += 4 buf.append(sd_block[pointer:pointer + VLSDLen]) pointer += VLSDLen - buf = _equalize_byte_length(buf) + # buf = _equalize_byte_length(buf) return array(buf) From 98ab46ccd92d198bdf858a493cd24ef3a79009fb Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Thu, 8 Nov 2018 23:08:04 +0100 Subject: [PATCH 58/61] improved attachments, channel hierarchy and events handling --- mdfreader/mdfinfo4.py | 127 ++++++++++++++++++++---------------------- 1 file changed, 60 insertions(+), 67 deletions(-) diff --git a/mdfreader/mdfinfo4.py b/mdfreader/mdfinfo4.py index 15652e2..82fc4b9 100644 --- a/mdfreader/mdfinfo4.py +++ b/mdfreader/mdfinfo4.py @@ -24,6 +24,7 @@ from zlib import compress, decompress from numpy import sort, zeros, array, append import time +from collections import OrderedDict from xml.etree.ElementTree import Element, SubElement, \ tostring, register_namespace from lxml import objectify @@ -1204,6 +1205,14 @@ def __init__(self, fid, pointer): comment = CommentBlock() comment.read_cm_at(fid=fid, pointer=self['at_md_comment']) self['Comment'].update(comment) + if self['at_tx_filename']: # file name + temp = CommentBlock() + temp.read_tx(fid, self['at_tx_filename']) + self['at_tx_filename'] = temp['Comment'] + if self['at_tx_mimetype']: # file name mime type + temp = CommentBlock() + temp.read_tx(fid, self['at_tx_mimetype']) + self['at_tx_mimetype'] = temp['Comment'] class EVBlock(dict): @@ -1248,9 +1257,6 @@ def __init__(self, fid, pointer): if self['ev_attachment_count'] > 0: self['ev_at_reference'] = \ _mdf_block_read(fid, _LINK, self['ev_attachment_count']) - for at in range(self['ev_attachment_count']): - self['attachment'][at] = \ - ATBlock(fid, self['ev_at_reference'][at]) if self['ev_md_comment']: # comments exist self['Comment'] = CommentBlock() self['Comment'].read_cm_ev(fid=fid, pointer=self['ev_md_comment']) @@ -1564,7 +1570,7 @@ def read_info(self, fid, minimal): Parameters ---------------- - fid : float + fid : identifier file identifier minimal: flag to activate minimum content reading for raw data fetching @@ -1575,40 +1581,30 @@ def read_info(self, fid, minimal): # reads Header HDBlock self['HD'].update(HDBlock(fid)) - if not minimal: - # warn('reads File History blocks, always exists') - fh = 0 # index of fh blocks - self['FH'][fh] = {} - self['FH'][fh] .update(FHBlock(fid, self['HD']['hd_fh_first'])) - while self['FH'][fh]['fh_fh_next']: - self['FH'][fh + 1] = {} - self['FH'][fh + 1].update(FHBlock(fid, self['FH'][fh]['fh_fh_next'])) - fh += 1 - - # warn('reads Channel Hierarchy blocks') + # reads File History blocks, always exists + self['FH'] = list() + self['FH'].append(FHBlock(fid, self['HD']['hd_fh_first'])) + while self['FH'][-1]['fh_fh_next']: + self['FH'].append(FHBlock(fid, self['FH'][-1]['fh_fh_next'])) + + # reads Channel Hierarchy blocks if self['HD']['hd_ch_first']: - ch = 0 - self['CH'][ch] = {} - self['CH'][ch].update(CHBlock(fid, self['HD']['hd_ch_first'])) - while self['CH'][ch]['ch_ch_next']: - self['CH'][ch].update(CHBlock(fid, self['CH'][ch]['ch_ch_next'])) - ch += 1 + self['CH'] = self.read_ch_block(fid, self['HD']['hd_ch_first']) # reads Attachment block - if not minimal: - self['AT'] = self.read_at_block(fid, self['HD']['hd_at_first']) + if self['HD']['hd_at_first'] and not minimal: + self['AT'] = OrderedDict() + pointer = self['HD']['hd_at_first'] + while pointer: + self['AT'][pointer] = ATBlock(fid, pointer) + pointer = self['AT'][pointer]['at_at_next'] # reads Event Block if self['HD']['hd_ev_first'] and not minimal: - ev = 0 - self['EV'] = {} - self['EV'][ev] = EVBlock(fid, self['HD']['hd_ev_first']) - while self['EV'][ev]['ev_ev_next']: - ev += 1 - self['EV'][ev] = EVBlock(fid, self['EV'][ev - 1]['ev_ev_next']) + self['EV'] = self.read_ev_block(fid, self['HD']['hd_ev_first']) # reads Data Group Blocks and recursively the other related blocks - self.read_dg_block(fid, None, minimal) + self.read_dg_block(fid, False, minimal) def read_dg_block(self, fid, channel_name_list=False, minimal=0): """reads Data Group Blocks @@ -1822,17 +1818,7 @@ def read_cn_block(self, fid, dg, cg, channel_name_list=False, minimal=0): temp.read_cn(fid=fid, pointer=self['CN'][dg][cg][cn]['cn_composition']) self['CN'][dg][cg][cn]['CN'].update(temp) else: - raise('unknown channel composition') - - if not minimal: - # reads Attachment Block - if self['CN'][dg][cg][cn]['cn_attachment_count'] > 1: - for at in range(self['CN'][dg][cg][cn]['cn_attachment_count']): - self['CN'][dg][cg][cn]['attachment'][at].update( - self.read_at_block(fid, self['CN'][dg][cg][cn]['cn_at_reference'][at])) - elif self['CN'][dg][cg][cn]['cn_attachment_count'] == 1: - self['CN'][dg][cg][cn]['attachment'][0].update( - self.read_at_block(fid, self['CN'][dg][cg][cn]['cn_at_reference'])) + warn('unknown channel composition') while self['CN'][dg][cg][cn]['cn_cn_next']: cn = cn + 1 @@ -1879,17 +1865,7 @@ def read_cn_block(self, fid, dg, cg, channel_name_list=False, minimal=0): temp.read_cn(fid=fid, pointer=self['CN'][dg][cg][cn]['cn_composition']) self['CN'][dg][cg][cn]['CN'].update(temp) else: - raise('unknown channel composition') - - if not minimal: - # reads Attachment Block - if self['CN'][dg][cg][cn]['cn_attachment_count'] > 1: - for at in range(self['CN'][dg][cg][cn]['cn_attachment_count']): - self['CN'][dg][cg][cn]['attachment'][at].update( - self.read_at_block(fid, self['CN'][dg][cg][cn]['cn_at_reference'][at])) - elif self['CN'][dg][cg][cn]['cn_attachment_count'] == 1: - self['CN'][dg][cg][cn]['attachment'][0].update( - self.read_at_block(fid, self['CN'][dg][cg][cn]['cn_at_reference'])) + warn('unknown channel composition') mlsd_channels = self.read_composition(fid, dg, cg, mlsd_channels) @@ -2013,30 +1989,47 @@ def read_sr_block(fid, pointer): return sr_blocks @staticmethod - def read_at_block(fid, pointer): - """reads Attachment blocks + def read_ev_block(fid, pointer): + """reads Events Blocks Parameters ---------------- - fid : float + fid : identifier file identifier pointer : int - position of ATBlock in file + position of EVBlock in file Returns ----------- - Attachments Blocks in a dict + Event Blocks in a dict """ - if pointer > 0: - at = 0 - at_blocks = {} - if type(pointer) in (tuple, list): - pointer = pointer[0] - at_blocks[0] = ATBlock(fid, pointer) - while at_blocks[at]['at_at_next'] > 0: - at += 1 - at_blocks[at] = (ATBlock(fid, at_blocks[at - 1]['at_at_next'])) - return at_blocks + ev_blocks = OrderedDict() + while pointer: + ev_blocks[pointer] = EVBlock(fid, pointer) + pointer = ev_blocks[pointer]['ev_ev_next'] + return ev_blocks + + def read_ch_block(self, fid, pointer): + """reads channel hierarchy Blocks + + Parameters + ---------------- + fid : identifier + file identifier + pointer : int + position of EVBlock in file + + Returns + ----------- + channel hierarchy Blocks in a dict + """ + ch_blocks = list() + while pointer: + ch_blocks.append(CHBlock(fid, pointer)) + if ch_blocks[-1]['ch_ch_first']: # child CHBlock + ch_blocks[-1]['child'] = self.read_ch_block(fid, ch_blocks[-1]['ch_ch_first']) + pointer = ch_blocks[-1]['ch_ch_next'] + return ch_blocks def list_channels4(self, file_name=None, fid=None): """ Read MDF file and extract its complete structure From 9c9a3681b1014927385018d57a1cd722520ee8ab Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Thu, 8 Nov 2018 23:27:13 +0100 Subject: [PATCH 59/61] better attachments and events handling --- mdfreader/mdf4reader.py | 12 ++++++++++++ mdfreader/mdfinfo4.py | 7 ++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index ef11604..6c6fff0 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -1231,6 +1231,18 @@ def read4(self, file_name=None, info=None, multi_processed=False, channel_list=N if info.fid is None or info.fid.closed: info.fid = open(self.fileName, 'rb') + # keep events + try: + self.events = info['EV'] + except KeyError: + pass + + # keep attachments + try: + self.attachments = info['AT'] + except KeyError: + pass + # reads metadata if not self._noDataLoading: file_date_time = gmtime(info['HD']['hd_start_time_ns'] / 1000000000) diff --git a/mdfreader/mdfinfo4.py b/mdfreader/mdfinfo4.py index 82fc4b9..4384841 100644 --- a/mdfreader/mdfinfo4.py +++ b/mdfreader/mdfinfo4.py @@ -1261,8 +1261,9 @@ def __init__(self, fid, pointer): self['Comment'] = CommentBlock() self['Comment'].read_cm_ev(fid=fid, pointer=self['ev_md_comment']) if self['ev_tx_name']: # comments exist - self['name'] = CommentBlock() - self['name'].read_tx(fid=fid, pointer=self['ev_tx_name']) + temp = CommentBlock() + temp.read_tx(fid=fid, pointer=self['ev_tx_name']) + self['ev_tx_name'] = temp['Comment'] class SRBlock(dict): @@ -1588,7 +1589,7 @@ def read_info(self, fid, minimal): self['FH'].append(FHBlock(fid, self['FH'][-1]['fh_fh_next'])) # reads Channel Hierarchy blocks - if self['HD']['hd_ch_first']: + if self['HD']['hd_ch_first'] and not minimal: self['CH'] = self.read_ch_block(fid, self['HD']['hd_ch_first']) # reads Attachment block From 2de0f24c9e1e452cbe675f63dfe51481abb3eb69 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Sun, 25 Nov 2018 18:18:44 +0100 Subject: [PATCH 60/61] Some pep8 refactoring for mdfinfo --- mdfreader/mdfreader.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/mdfreader/mdfreader.py b/mdfreader/mdfreader.py index e897f72..38cea95 100644 --- a/mdfreader/mdfreader.py +++ b/mdfreader/mdfreader.py @@ -141,26 +141,26 @@ class MdfInfo(dict): >>> yop.list_channels(FILENAME) # returns a simple list of channel names """ - def __init__(self, fileName=None, filterChannelNames=False, fid=None, minimal=0): + def __init__(self, file_name=None, filter_channel_names=False, fid=None, minimal=0): """ You can give optionally to constructor a file name that will be parsed Parameters ---------------- - fileName : str, optional + file_name : str, optional file name - filterChannelNames : bool, optional + filter_channel_names : bool, optional flag to filter long channel names including module names separated by a '.' fid : file identifier, optional """ - self.fileName = fileName - self.filterChannelNames = filterChannelNames + self.fileName = file_name + self.filterChannelNames = filter_channel_names self.mdfversion = 410 self.fid = fid self.zipfile = False - if fileName is not None: - self.read_info(fileName, fid, minimal) + if file_name is not None: + self.read_info(file_name, fid, minimal) def read_info(self, file_name=None, fid=None, minimal=0): @@ -1258,7 +1258,7 @@ def merge_mdf(self, mdf_class): mdf_data = mdf_class.get_channel_data(channel) self[channel] = mdf_class[channel] # initialise all fields, units, descriptions, etc. refill = empty(initial_time_size) - refill.fil(nan) # fill with NANs + refill.fill(nan) # fill with NANs self.set_channel_data(channel, hstack((refill, mdf_data))) # readjust against time else: # channel missing in mdfClass data = self.get_channel_data(channel) From 3f14c53dac7b1e06628f7fac4b48356650af6425 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Mon, 26 Nov 2018 20:54:10 +0100 Subject: [PATCH 61/61] docs update --- docs/mdfreader.pdf | Bin 225475 -> 225801 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/mdfreader.pdf b/docs/mdfreader.pdf index 17a21a53d7019824a82e59656344fd92035b32e2..e1297701a8612edb1d1889dbe060a4aedc713286 100644 GIT binary patch delta 30697 zcmZ6yV{m0p^r)SaoH&_S6Wg|J+cqY)PRxlt$;7s8XJXs7ok`yL{p;4f_r2eq-Bo*k z=&tUy*3)Yb>>@@UAl7oA0$7rIA*hp#P~kz^Yf7}Nq~}d`rx5j2Y>y0P#CAo%{PcDO z*{|-XA6CTY)z!!@Q+lwwh{)N%PnT}^KaoO4ICOane}pmz-NR=N-`R5?wtAP@QgS&M zj!_JT##7F#Q7R-418l8-lUqIYMiojx4%eF1&$!motF#cBoa`xS*y%fMw;ZD@nqpfZ z{Vm&IKc~AD;(%z+CQA-IAy$-4>yS&7=NrC3v4oUu3Akd^T1?KwE|og}fa6SRDeB+j z9on6ldZ75poCSg;>ss2Qhp zXeAPRC&Va83FS;2eA%e$ZpX|p-O^N90_B|gfE?txD6Jqj&-7U+zC|W-+)nweV-#r7 zJgxzl(VMA=QF3f2upP*{*;7cEpkPZ(u~~ZxXKCUVDFwjeU>NqIlEBC17 zV4ai77P2#wPl!CQ67wW}%jJNjlvWIiJi(rWegXx1OSF>)Qw2p+eFtBSOWZ~7ib2Uj zJ0qgFRG8U_z(pD0N-D;$OO{!HP&gYb5c=&LK_gwLlpzmia1EnU%GB!>CBsNVNnRL; zt<3;PAIiKSv0~L;6-9ky7n(|*jk3`86K_;@AgU4`$SZYLQe8sBN8KTTADX?bE8F^Y z<^YQJfLHBenx?SaA76B}J{|qI8$Vfnk0<$@^EuuKB~W<0kw%i`mwRNgCzM-SeZgC| zId6Gom_B6w+QIN_SND9^F8J7|;_F9)vl|HM#2@P|dTITTgS%usEr~;0m zuir8351sIT7u^9EJylnSAg?mJ~KNTeVxtvz|wGnj(mXAk19$Lp_jpy^5C>*MQdc+;3{ z2wT)W`2jFw98q8t%1WC*T>H_xExq%1^#rVAx2JWv$9xU#y!XmF0Ot2^f@J829gUOh zTqUBGpz_9c$%V65-|m2tBpnl*FLmRs#*N0g#yV@&`J-ZbPWrauqT(MP%KK_@-$4s6 z1;d2wpQX2wF@oDK_c4N?{cB88_D|)s`?#~gs&u!($a}zHf{Uv@6!tx%?n(}Rh z(r%?{id@bF^+?7%tw8sC;+5R~w1yO9qo<7|2O4Y$aVOoRC>m)1Y|;Xa4k9cZn~{;y z)7vRhW-3e)FD*HWDj6gx=?V0UMImrFXf}8cHpz*W5YU&DKr0C%z>Z;Ak0AWpXI0=o zN~YgXu&p7)>keH(HoFL-KXp}lzoVK&|A_U4y)v#>1WBJ=zIGe%WBY6jO(6|2gq!~u zzq+a97f_b#_)U*=LDxZ;NwqpO6>hw2i0BY$WBJ?`*i!!mH| z)Jv330##ri372>leWmC$2?(Ou#$6fmbo1)g`aLbMmigxs=&8z^Qym+olQ{}+_U%-X za9ri=H^h05K5}YVa(f!3GsGFgs6*v+w|IZM{W%B+FT~8JYe`#b!&vnybu*jVBQAzX z>d&0*NIO6zDEF#iUfx!y>tR)SNqP^A_XI7~-#1i9y7d^&#Wo4~JdW!eK8F50I#*~3 ziw60wp!l`*otiDoNB-XN3)-%MI6p}l4XvS+esKO@c>OQbbUwm^s3x^wwtz@&g|Vzj z(iUr4NwSHzGh|dwf5K%{b7*J69EG{wgtNNA$Vk=d9EoOFq1Sn z#kdG=xQ?bsob@hR)xgeBEKzt2i>m~V z!27Fnf4T$3e*%cp_eo%goMIXcnJpfVTiy*e9XD1B(f708@(l2XB0I-F)XwmO=W(F5 z8fkk(pe9MS^u@r0uiWLeF;ZRP!B#|nyTk`Y3e!_LNFeWl#D3jsq-*$EGH?-P@wyy< z$L%yUBG5YFNCX4E*V;F3hq3g}6?|hfyrkO`8a43noy&2~2tS*)+b2 z&JnMpd>c3h*6iJ(`FAd8%(#X97+>7Nb`}`XrBdiFKqZ&Z0_1|cc1R^fOY8Y$&$R2( z*?+Q4>`bCWQ|?XqNuz~>_OOLg27MfV7nUt1p+F|zsoptctuELV^5k2bXm;b!dl)4B zn0x1!Pk| zigwizDYWg9q~Z{zIsQsRtP{ncGeQ5wK?V9fip_*1IP&{^KwLwSSJ`c)rQh$g9;7bT zMD^Oaia2I$5&|QJ7Uh+*NUEPdEyCTZO*AkuL6K_CK`=2#P(U2VTVwkZb+`&GOn;P0 z3%fTXi>)k4l)nf56r#EFeujJ;;^_wjLvtFv&M?S%alL2+P=)4$E(@1!>&5(Ej#*}7V*l!wE)jnDCTU_I0DJlg^eb+m<+we+NeHGzHN z(HZB(79!H&C+>u}>|mNQ6o49>nI%csg*K_@5$4~awnDW<#+wwK$(59)vpyf4IjiJ5 znx#@GqM|Twm;(tA5a+Kd%Phu%1@;YHg*yn+3ER=r+jZq^@X7hNo5voKXsTHAi(#Un zqNM3?cp!UZJR)nw&8s6H=3#}rUi?~{diZhVpkb`zZJt%6*?!F+CsG6R2q`{wF+VUe z)&UA1JBAI+s1>Kv#W@@uZa%D`h|8(P5c-mYCq3d>O0!w`vo{y`HQ1i>!O=G?yYZ+o z7u!-T#<0==E0MmsrhRzIr!|Eoee_kf5nw5GjI$0!xIngeB3RpNfqagDI@-i*%7pkp z)Ys8ap}~J*GYBVHJ&$l>DJGZG$%dHZbq1>H_d>-w%v{f)FE#)l{jpA&PWYGnF)$jaK@`4)rI)1`O5^-8yU z31WkXi*H}X+12lZ!igy9LlO+EX76qiHw)u{JeG-(Dnuvnau(B&UtrW2!C*dvfs~*^ z-2#*$(+XMUz2umiLf!~siSOBB(nl$#sd@)o3P|s8jE*Y5Fq!CJ-FUwdHJL0zye=X3 zwWp#RkERglQHq}-y>kBHAzGw1W~`^fiT*{L_7H5bz%I-hR?-sLvfyW4{Ds)JFi9uh zeWtMAaAjZ>rOug8w~UA}%IK}umqG~&KrV<-Dw#GkT2RGAU|M|1LMoGPM*&m&Q#TKD zKt9e)#=ZAs@JR)>*mInA`!nja;q6vtp!Cnsq>SN#iIm?svj?h}B1L1TBintVxhYT)?yog54{@`1|RM6AZN8zuyZ#G&ZaMV@B4c;cO;7O2l(2l${-gn z|LkvNe>+MZK@zhLSZ;iEgUhvStz~VLihNl^^916BYm86?pfyq|K)HiXCEn2zY)oIv z-g#)+HB0QK!L(C3zvkT0&|L`R6)8=cEl=~nl7|(Jl0)<~-qjCLlpF7!GnKM5Xq_BG z)?_s5ZkUH~af!trXEdHTC!k}2XY9^U#8QvA(wj=Qep+|3gG+PpbvNL)I{V7X9$_FB zyz=$km1+ZGXju9?dfDB%Bo#;0hftkxoD$%jm!9LQYq8zpNFUqo!~GrfGJ75iI&z!* zR7}Nt_Sm)^bK)Xq(D1jLd%35`T6Xm_eocTfb(R;>;1bmFPyvOb9F3y=EHu?wV|7+) z)e8dRo-DD*4Ro$bv-!HEW;AW}?se5${7xF%kM@xG?QDVBf_q-iUn9#|F_dZrOXbex zCtdn^9=4W+^&5|#pLPxOu#I*p6(I^p{iY@-30M0F^Wy4auZ6`M(dZy>WTd#F-g#Mu z?^?P)Ol!qsw|350FMk!crR{T=1lQ6&LK|&C4gJK^)zowbri2XqL^voS7ySWZ)DQ!g zxJ%58i!wE&apvpdi5lXCI_vn}THry8wz_@G69v8Qkx6x3d!g z{(T<4PFGsPLGTxBY$@Mc=IRp` zKT{ty$zW-w7_bk29Hpq1soY4G^w7L`dXjr)u}EHq)#GH9v)!|Q<-gMsEo}@QfDX>a zn$!b91KLy@OUz!EWmxjTV z{cWKrIdKVT5YmHBu_IrQV#-!j1|HBv;HUVXRwxHZ&SU5(%>?}e{bC4^)oco8-0F!+2Nb#%MJTwfQ*@8<6sZL*OyI&HSoU>P zf}*>(Bl}oqR2Z1;tAGybmu+ZF@0FxVe~490oOtk&+%)|`h~%4M@)?ZelKe~PaumVK zeLV-CmjbUbYZ`~ONs>IqpJx+VH(QDlVYg*g3{CJ)v#Yk;u}WM5isac7`AvN%(ILhk zta;iO7GXAF;qHn@`3I>7?pG`TxzFbn_RA}XzJNJy!a#xQnW*9GZj3ZzZFtl~HI}2C zm6iP`KACH=mu1%{o$2+y>g5rQX9ulO?6&_|MsODHB&Q^_7HC8O0wjR*AEUQWp#l`4 zlAN^ATcWW6H4te*;1H-Sa(IAbU{V4$TFX5VfC30$PjU*P25HGV;Bg{!UDwPop9+(z zkdb3ZfKdjngV8GuQqL^i^f@(0&JNC{ct{w) zLFyHt+i?8E1L;uwk+#pcEc<3)~4*hQ(bV8vk=-}&}{X>_asJfmQffxzMmAwU!a`~)dZ zo$(~RXh6E8vuI-$9c=Fy`1qb#pt;jH`1ssTXm7mAh7T3 zRt>w7K&di9*BLArkpn@ZO&wZ^tquZ`2^y2d>!k_I$YLH&X_r-OYT{)OHGn%{(33C# zFenUFdPRc(cTZ)lF<}Z7eDxa#LB|a&ICQ-~o}#T)PYbot2`qSVEJCVUfg#)X0t_lM zX}7u%l%N-k+;1@y#H3*~quFbqRYbIh60As4Z6?lBUV^m5SgCrAp^?BHXG zX0S*rp%&R?pm(A3>gUzbuO8?V#*VF}M{c+cC3PuyyX|W!_Vpe0e32R`32A(}329?w5MJT2J1BTVqy9a|5MgivK9S~>Fr+Y-SC{pLWQ-gGsPMouFE%~`YO%>%C2Baw-*^Kd{ z0iAtIC3%idoYV87n6%*L*|YSu&Urfs4PryaG46D53OEnR%HqAe-Co^cpvm2m z=<%Mgf#6`Lu-zM9zq)q3*l@!ff!iLRnx*rW|FKyNMe*UbEAj3(Lsr+9z5R-u$y2Ov z6EUc_*NTeNx}ic3)r-n@TmEZ1buG(vbx&R=da4Y524P{W6XaH01N@Ko)lxZ>R=pLE zURDck%Np4?Mzok`^Nqvpw#V{bQmd)&OZ2nzB`oay3=*w6rqW@jr#Uv=rZeuI zHVrBGrdzXY(?+-&+_SsT2&jpJ-89^`q@vfonlfZs9Qe22@>QFCnw^ict9;8W-)9^` z>vq>R`)6Nn%0dUahIN}0L9=R9Kq=*TM~vrfK+Upo)`1_RZ*04pkIsKg1%JFZo@DGsUxMO*`I zx0E4jZ=HUE#B!daF%d_t)3QEMuOTB@rjsp4f1&-xLQvq$?af?Voz0DZ{6`KZHvcXg zi1*N2;AsJ@KmbeHt}*~U%@zQlZwX)oOalKW8lWYq@6)%$vH>uFNy7VREzMj2eE{HJ z%n(Csq2vLe008X&y@%E!#|!uk_!l(LT0Zyy$bckbRJ0aC0YK%y&!p{Y0w|EVxLDvA z<;?9ZU9E^%SlHRqgk1qNAXx{z5tQ!hniEss)64Q|O^6_XU@n;uICkncX&}B?hSX2& zLLudV`|JC~+P3lVR$0~xfOEW!dyCe+o8RK&366uF&h3&cA+iczC}zGgodhwWFF`1D zV}uM+=mAMqJyu<^O5^FUbhM0rbAEI-mTVX15GMZ$fk9T;ppg^yOSl!=t1px+Ezl>i&^cTf!sfbme=@2BeckiA6=tJ+ zz!An3@+oXbW78?&d9Y>UrUM@12#U2ol-I89p?~i+2ECc>ryDCeXRQGjU(fBF?v~yz zNB{CH5h*Bg4oB7nv^bYGMCA%;?~0+f(-Yv((eLyPyzsHksZyP4)2vDgTGC!k3^g|p zS)L0@0uxg{3aGJn(}4i(1*HPR*Wsmn^?Iz_sB55Gi+mD!(D&YZV#pZMsf|Ul5Hj4Dc#~Jh|MghVl#!pnm2((=3 ztl27w_MIHxynsQ>upy*jMs2e?IAiqo5iep!kR0PMFBChHHi(1;^vvt3_{z&GDul{V zfABQBfzF>G>##-~2ZPQPyB-X^M~&ZakBQ>-EZfs(>P?zfG} zn8c&b6ScX_@3~^V4OhZF6Nd)B$J3IE!+S%2?yqNy_sgNfY0EVD(2) z2ldVvAkyc^1dBmi=pasZ+K4K|2Q$5dFokJcuG&fJQ-mL>&t%%f@x0V>zF`FjYc#}d z^%+$RAo++Y!jO8aKYXmkr@N@E_o=Xzhj$T|gaeQk9JdFAsO^`K`fFADTeomf5$oc& zgr4IN=&kNbhlH_RaV0G1yi7PrpWD$1LF`wYr8(2H*-6x(X2-wRtMBc6Thal`M>$zw z4pq0soz=-*%t2ewgoD$QTMZ}2g*{TXs#BHrtQG4MXB-XflmB6+BKPHL;D7HmqU$M^9FK0|3BcgoXZ#Qkjsy${;%18 zpf>$ueeM0hr`}{nS(sa=HqIAlR9Gy8l(LAbKWgdH3msyZf`&=mEJTuDq`^Xxm=KTd zKdJ*uunZ6mI{KbLC95V`L?)^MY}3x~M+(U0;*Y3Am~#lU(hI-cCt3mZfJGFBJ`(}k z+No#r<%I&}vV^#vec+m3=90&ijs?!aJp%r{}mR*)+j@tj#Wq;e6BNf9u@Ifki&=L+Dw z5w0Lq?s3#7j|D5ep8O(W(5BeER2O6|Bq0oWqQpss`hG6|)PVbwL4?iv^U@Y7No_9W z4#EWGc>pi?BFkylVC?P{NAsr^^jZX(J;Ifq+X0#Y8KsfX>z^f1STFMUKC-vqVe`(K zi{h{4EE7+d3t0hMv2Qae-aL}Hp$2I@B4|adNf@*i`VXGorLO*w*|EPC-78#Cz4>_6 zcn*^-39YJN=h3ysB>#jV1`>$}AB&wk8NZ%jGmo|_<^76-xzCv9QJ8_EV49;cQ6Zf! z(BWuI|AM&UQsN2)DZmFYw@`bJ`u10ru4TD|Yv~BD2{{5A@<9OW~9rp0lxdJ#eyM-ibMLQ;B0?y#5mD zWo=Y3Qb1-wABuP;if{2=kGDUuv%}SzF!E`ngwv8khPL+PBYgkR7AjOYyE2f(VhWb*|&L*UgZ0nz3(=*+J14RbSaKf2WtCPyz zU0uzf+r+~`MCxrds@*`^=Gin(zPrEN69S8O`t|m$NHu8b+M`9(VUBW{o2eq-X0>VN z7J0beEyAC|tXZvEMDLA+BA3_l9Kl40OJ*m23`q_^6{>ZWB00$&jqZ)8vz4Ol zeSP+-DY0;e)Z!1CUk@;Uny9ZZ#EO0#;%xAwv0h5FvBjpBUS?x&3d)nQDIb%Sr}@xR zt+H>$PG>~JVpYGyz{)OfBPbSHh)*asy1PJTNG#_qlm*GEK(>gcM(n!##virnd!z1? zI+nQZXJwelP2G|)95U$wXa){6R4dTHac|g-vU|VfdRjp^bWd%fBZ}5-Vv?;SF zXoW|!rN1DiDl%O0IiNjhyLI9O?~#^l7nf0bF@tAY#6Ai#bFyqe5#BKQNved$Ml3W^^}q!wVo5fySn}A|6g$L` za;X4}-qw%3>ONlDt9%kD^nkA-Zs@C^rB0=cnM#o6p+0Hb&9y1TazA(W20AU5?41Hm z14WJ+Md1J&6ZE*YEHO5=Aw76f=Dg#gRa(QoOc^^-)lezNiUfUu6MVjQWD?tCfws)95*Ft0jr}%i4oR9>}`~1ncv>M>w7Xc znw=m(b!sSd_8Q#8rk0TfIh28LVWiWLm`b&-UeC_Adx~)8nHa@K@ z3VwY&Mc>y>Qy6Xu<~;9RJ^6cG!Cx3#nYHZ>?ILg1nzMH*2hw z^~2*rXN7SYxBYs%0%jHNF{?m>s;BOep$5-vQ`m~wr_PF|6KIijL#50*Klz8_DTx`k zGGd?D!a6bUbVhB7YeN4Qh}MMiA$onkV>_@OosTaeRus(+`=0^21MSi1&`iv`|DYk> zl6YDqJG7JF&U^HnxF-Dn2WeBf00z)~{4w#gXm&Usk{7|9N!ko!_Ha^X%ep6Qdnq}T z_q2i}Vw_ z7P36+-kr=rsUldunpmME(T$(mDy8pO2!OyCt6+k)5ywo=npHgwf#(hYXbzaNHGel9+H> zV`X9o13n&*4|OWQg8LJE-l*PE!|2P8vI8M0K4G_x5py=){IQF!pAV@JLxY~TKmF$~ z-u@I=%%aMZydP!Ip#Y%5L>BQkEvI) z?x7>fSeCz+zjk)6mJ*R#aJgTZgjnl_9`Y@}T@;31$CFx!)A`czKbboXvn~F$~^LXIQgy(vPp$e>*hdb_12Z(jW}7wJ zAY9Bc=Z(Kp-QFURLrW|eMG(>wHS5Jjq6YgJ(gk}^poXQ%fiR{_t0_=jWDy|yaP3hm zW+-S8)v%@P&xHEBmRdL13i=1qrHKp1hjL-8a_gB_6P!F&ZQ050OT(w~YQdH!?s0cU zi+=k3BC$kp)KWi&fHHF%dOC{~1FM3}j;2WyzEIPZ;v!lz>3}x$}QZcVpC^M1g<=N@Gbf)+8F2hl*LKUgj;yyo#Lx z@|F}lL{n6|E997PBT!e7mbC{6@t3+#TAFLUYm6ZY9T*MB)zVRM$x*tGZxms-6cOKn z1s+1PL{=a-t3l**8tpvN4~R2N%9z^Xp-WWo8GhP{wvS zW3{5N7-Aj>I?TJL{Q@?Q=IkOm5$e)4#VMXI{_en0Uurt|)z+ zCJqvfYox=-IOeoZ&z|Ez+`$x$@R`npRk1v?$kIW%GMbkOrIhsi)6qxusX{Md4B+da zS`<;?84DYIx3SAw*%i@EOZs%BSc~yn4~J3v-IjQzrus&u=hfeXM0`P(68ytK!k7jD zbx$kDO8em83NAalSjaA?c~>r_eVs8FExE|Hw%ImM^@eK6v#L}M?h99On#*WGaU7|bX9}23P=T&NzzO(>FqkDX!f2(1%_EU~ zUV^EKY$Q;z{G(Ap#G6Pb~N=J?XfsZ z=h<8Y#qqnu_XoZ2Z5<&oP~iuERF_j_yPrSC&JEJ!_a5WN9?pQ8UtS}madqTkao zq$qL24FF=v>dFHK&C0gMUI@;LYKFf>3!}ko5PLLH27T>IcsB z$Kdx*em)mLz`g^vLc!3ADIW6_wy8fo^Aa}sFsA8f1#wMSXWF$1fD|B}c54ElO^Y`H z0MqK?{4|7^adPXwI5`W|u%JP%ObnV*6;zJRa&_Vugig)l%6 z3*%qw7&wlL`;4EB8P72hZ#Y|n70uJ<%?Z4Cy5tba4R}mxfonsc39rCJ*gugb8 zYx|g0A*hFc++WfHq;JS22AvTYhb=-L-_P+*@$>_B2!tHjxd@R23{U}j>xb#Vw+LL= zTxu%|@R?$uJp_qi4*u4Ftqo%AZ0D;XP+{G*gY_W!#fc7+yo2 zG4+=W7VAmei##kemz^9Et6qOtCs=vFs1iUI7nZL5g@Do^!g%Adomr%PaSW%nSizU% zgm15nL{v?Wty4q#?cVD<_JU(`Me4x^Gg8`Sy#NSejdvY{q1b-`T3-FZCEp;#LINDR zatc`RPaTS$s}|$;S$wh(BhnlJJQU5$OZWK{-B?m1i2|!es=B2@3l2rpB1GRd8UA{A z-9-A5Nha1?GcL}kjK*inCp5csSwO4uLky6f3b(h?t7P$rxA3|rP7JSw8$L&3t_sE>j55BD) zZwHCwDGpKMA3Q(M?ijbY4`lfq^2;~Ed~2u?7XuL9!MwI@N0$RGY#*)5*W-uH%K1s? zk>wFJ#jG0lI-w&Lt$4=gTD21Nx@X!~0)4_%mKO6|b(1(%b?sSvO~o&& za*B6A_M)9qrfxE&2;U`n)r76!0k*fXqI05vEt*Ih3!?>YF`!^%MAPq*0btfJ+7e>b=G#>WZ4(M}g@?tI*mWfn(%X@QuW0Xl zvoyJg(H1W$UBNFDU@<>he4{q>i@htpkfjMI-PQH!PZLoG>$S{&xGPSX>3h@Y>cTpW zOjHcv*NU0{rf{%8r6F+B5RZ!ViGl((!p7-O(1cDomSC~u&#g7pIjvr8dgQYQTPnn{;hSvEj5~beI;TV}o0p&g`3DX!JHA%T#W>4F& z-xI}N3FGD{-~NdLGyqppA2}uRKN0YMtN=K zxsX3s!kfd8svD?+pgIBt10J@Y^NtoTp5mRpnF2U0-1+kflnY`F@fBq$ep<>meb3JB7L8*=NZC$}`CtqE_XTy!ssJ#=Zx5(5-vN>}K1X z-a5&qh-NIQrp##3m)WGrjvzIOfbeOmV?oy|VQV}<4S8gQz!hf7(UTRGV}gM?P!!^6 z6FFyeoX_3bOdC3r-Y2NjR|@U1yg8UGU)t17iAo?V{O1$c96R7kb%KxSCIF7_|L_psd` zRNvtHEusubDW42GK3V2aOkM`AJ~!Llq*~5U@d!Hl@v`-|m>yu=$kFAy6oG z`;Aq2$pI=R=FdzPizLvspq{qH>@o;VL>U#BmVmss6{`EOdcJR zcZF(IJ#&Ugs5T^ZeR+NB6AiQZJM;{{p3^#9|2}^+o!$2c#QbLl{(=~muL=H{ zf#+TMK+?39WkJI)=f9tbF@y}ugjZW28Hd^i{s1oVA609ni8O6mQw5Ocv@QJQL_=RCl*d^dKg#G&V`H zgCj?>k?IocVWVuc*93BhB|kvnap)kfGHX&NDyB$xhEHm>7AZ7aF4(L^lNUixBGJN1 z2MfZoos3HA%Q zY5wmv{6x~VdKb(=ZH;jZAY>iluLSXR00dqmQnNBj53*NYB*(vuPWgieBP0dSE?^e} z1Lc?PAiW(l+hAezH#twh1DGTt1-^G)09g280rH;`(cEtyK;{kNagu4PWNIyoP|BU&JqDa!FqwJ+@mp5KaW6Bp{ATsFxQm&1d~v5MOPl=u zkDzz&Zw%A5F$o~(AX9EeI9wvv-54<=bowbuyzIVWVK3o)tiXW3DBq-O+D5o1xqin} zbN^IJbIcek;Q&jL_k-JI^E<$BPQ#>%Tl8JRZwR(z@X+x8Ow&N z9ZRfRgI{7X&t7uyEx#WtUi*ru^Kdv?B(;y2y&P7f!O9AhZ%GcIn!#RXSID~= zFh!HvR2_$07ce1jnB+tYS#C;+-i_0h>s)946xf9;Y#;(mtyM-g z&<}NIY_CIL_O#Qn0!x26#Bwtc#kQ|p_d1f)u$32JnjkpS*237QZ%6-kKoC9+#qT2?4jw4EJ$SS3N)rZ-`IW|t%eRGxc{E5h*>m(WD5*&sQX`WlWa*E5X*@U{jESuGAKj0pbyh#=OD z@@6IIbbbD)97^y~uwEWaMJLw7h|O>00n6$w>_@f1U^N9xgu(&K_~w3=I>98%vEz)w z3ud6mBme;6K|$!eb1l);^o6Y6K$y(3(ond5Kas7xxOM^}x)4oxMk6Gmyv#^7x#f?P zntUccM#&TqMdw+{w*{uy7*<4gvGJLm*cTe0QG!BePn2)7rjAvFOQJ1gkZ)6N0R-wSv<5IAE@;^(Bz6p=sb$DYU)ppB#=X2SJiPE5jS-6CAsR7-m(hAT$ z7EOz##V*XZt65i+(DioXc;%5Q$%kKx@@*V%$QZtP30^V72!R?_hy&Zr`NgejLJv`Q zc>~{h{5zty6=9l4JJwJF7Tad8A0v-XiQG(}soT=N*QEMJ-=FcWGd* zZT|$N$8(N=eU&vfA^gY7&FjE>$1U%g|8q;n{}{@F8taonRMRr!yZ;2G)r21|@4_p} zy~MjpZsb+brFDyC7ysX4jzsIvUukQU$szyQ&y)+>zh zke?@4{y(suY^Pc;KgL1+e?#U$3*{!M`V`{({!k0W&+pvwp}g--Xu}yE+EVuTVM<*G zGt{K()iJ|Ov0nN~nwLbChb*lRh+=#hnEH2H)g2XL#a-L(BcW0ABna~)HV;rBZ8MH^ zJZKaAM;qNnTr{y$DXMeQ2&(*=HTc2=n8YQL5y;TW;HDw*VPyl!zqCRD9BkjeQ9#8V zILoWMKH;yNU?z86_x7vB@i;4N!ryrG_gRKCMio?Hd%51` zC#st3E`<=~&U~0vmYJo(xFm!Dtte-T73#VgK!_#>Q$m@&z?poBBUnBi1lZa{t4PjR z9ki$GqOfDE$P|!c7u!-jDo3rqODCKp%>TN$vsSfL>&xb7x-(XAvB5fY@4;{Kj+tuP zl5{5h-GHvUn6$6$dtSMii^AV*eqNbEiePBUxgZI!ai|;`^HWRwpuvs@EiXO+g9m5p zphR8ky(1NtvMb`Q)>^lt|Fq#Z7u>XAiy&Z$b-^^Njt;C2!rg@gcW+fw1j?6 z8X{?n++@Xcl;AC4i#*h(Zt(?bW!t!5yXWW7zPjH6b1Ju6jl6J zE>J|+ke|L+b**Lo1{X|9dadP5XRIi}^N;9bhX=W%5os?5OZX`5?!+${DqF^Dd+#Mb zZZHtZ;!mARZt?}{^ zdNmUFF&pvPzCO2s>>!gC1&3XKy+ncaXIibnYrlgmq+JUf&Ce}Sx+qAcpLm@()CM_= z>~6Jd;;~^p$6`K65Wu%-v>0f>gCoHM;thz1^1#^sMcfY0HG;prOX_Y%Qg`drzS*mI zU>(mK*?E+<7SoDv{C&=|Xqe@ZAQ?c1Erhjq$x(ocQ3eU0;uicZqjf#~#GTv#6A#8@ zom%gxtQ^~BU2{*8Xj2SNRTVKJO&xI}i(|^BWn$o%to+Nqlz^ui!(dJfKH?{jj~vLs zqqz^^xYfBO`jGCN>jcq!^;f@&!CqEp-Ukm2#L=crr)w;=yMm|*fq4*;h}?d;5b`XR zV2T1PY$z_wf_Rgk_NEhc#9Oyjb#7B$T&_rbpuj_-o-qeYcpnsxL6D3mJ?yJK2_764k=4 zd>KOO{gv%;$mqnb(s~(RVT}H?ihpO6>WF%$MN?NJyVW?wm(PYYoK;AQMzk_NA5|}T%ZAM|HA$%p+k(eulNnZh`*9_vpb+faT+G~Zdm9k!Z!oeq-3^nycj3h3 zst@(_gWMgTOy0J~UHdmrEyoGXq`J{xN&S3nQY{AyHn#4I>0Pr2Q!rsc8IlCcloK5< zC6Mp`*V|i0#q~UY!pscr?lM?#cXtR7JXi=G+}#;mg9IBO1b26LP0#?r2{3qY2(HWb zC%gZB-t4>Q)ag6bU3IJbPT%e`U0wZ|Kmmqea!0q%tPyn+*kxi6B&zWrXmoFZ2Q9NS zlMM(e>^=20&-~+(WEi|}KQopC-9y_s1$3bJ4i%YShxmB*!*ibB(S$a4Uem!^czalg zPalxt8^{ONjg@iU+P@>#T#@3&ptfnLT*Dw`f~8W>rj|t=x2DSCL>uzd8+~cvpe81V!=#OGeMKe(7qX&(E0WaAz%Dk_A75vs4~X)Qa>gHAY7DXB=tR#SO4b$ySAR@d zs!!>&ULtac_pq1dv2O~CD*ioBZe5+7cZa3>M&K7YFvJZ&gdPdMbX!OYocLwcPVW&f z&oY0x()=RysFFTE^W12v>)nho*C&5HuD3ZdUZc6F^s5iEux3#{?W|&eeJ4qWTm3wV zv`IVlqrf*DvwBO4-`|G7$cy^twEC+HEORbyLsN%I#wp3&YE|nxc0p%VVhawvq-x4d z^Pf!-(O5)9AeJ{bli{iFN_(1KT$XyHoY9J6(Hxuj=yR9jF0`Y>_yU?m0y4S(+u6zoJ@*0dzeei6MixNT zeF5;0kFQRI*I50!E^Ap$e7S!+5y1aA5gPyNMCkLyD0~s8;wunH4&A#u+XciLPF7Q1 zi6!NWYkpv+E2Cq6j~5-58~runXHsjpiK4~lKV?l^!^u9Oz4Ssi*vRW2(9Kk3RlO29 z-w#s}k5&vPqfac46x>>>!=ofa+;JWXY7d+WOQO@p0q@4pUq&S~+*E}fyyDUau+@a9Tw7XC8Bgb*X~W3qin zo`<2#6)q3ArZr+1Gx|>pt;zUlI&Gn-Re5jN@$q3c5IyGgaXKSZuAF6h4Tw#Mok^7q zQGxZjDFf}qGH$&I*XEqn0M2%#4KRd>VRBCRu%E!tD>(SFVpSu~NSgz0?AN%3gP&$) zc2rxw2MRd@1W)^ajWi|hA>@;P3tk6sWT;Hi_KZ2dzZ?AkIq{K$EIjZ>)rh_NsY1?; zy0g3Q4NfE1OacI3Cg8RlvHo1zmdmrVE!Dd}VO9>=Z{q@o1m{$CpbLhw2{RtCryJ;t zw^CFNgY;R2%*hPef2zy1ek@C1purRb-j{wU>yx6bPmjDtma49U90Z}}54VGuqa45} zg`zaUH0etQ)(qAu!K85JS3@!R-VR@)2uQ~|+gH21UA(*>Ue-@$VJnf5BYPbKU#DJt zD03jUJ1~e>)j&@+zd66_8U)Ws)_q5Zgl@5}kkG8|;0Kq6w1rGZhpr z(2~#8^M}D79$6srRl@bnL#0#_#p)RA=K3VslW{oxKpQwFl3^cCjS;5> z1~y`!Xe~%@W|KejP22ll9N8@L_k?iAe5!h$HA%@Paq|m5p}X=o4`#wV!Ei zkJH;rQiz*QD!oG*UAkg!5>2uBS&Eq^{H8xBPPiXeLh2C?2qQ5?;e3C?4NnuKkx@#k zAM&<>c%G659x>m}J!S_H9HJ1z3dTo+)?AbYg0LarBtnE0_-Qg$nTMcseQBvp^#oRZ z>Apq{*OO#=LhKDS#w0@Y88-(J)5Q4CVZX`d_yY4u71Ctqir+UJ5E%bDrv4RQB#9Qb zIA-vhB!qu3KZmO^O~rEU3I9oiy-6@MwFd5O z(B^m81TTNM5aX=L6fMg|?%v=TEd5?{PO`p6 zjcVQ9^N#_jTQluJ~-L%+tG#=;@TSwJ6ck(QE~$byjhTR_qwHQKc&i+7(!7=*xMqI5DN^v z_m&7;i0^sWdz$L;zdbp>;jNsphLGFB@_PT7T z)w*_l4Jy9K*9 zWKHE&pJh48hE{z(h0MvHr!7VCdD83O7koaLu`@nRP+G#4Rfpd;$1W5c0R^XNT<|}x z>0b*O&^d<-N@YH2NPi(1`B3qs!7c#jVynsy*7=$&0EZLMN4WPLZ}5Y$^DHDCPOid* zA>Sa2GA|q8kXvJoc8`HR-TQTm{P`1dQ|8VGxjuIgHjsUVL()1}YFT_uPcrxOIXE5< zew3`sx4ETAM1HHgcwgf~92w4Z8&WuP))i^;T755>KAGQr8INER|IOUwMw*bHu(>B< z36G9QsKEEM2A)lt&~q>}S-dWfPB{ z&p=VI%4n}iAFV5BdW-a&QBgf$)(EK^ElSJJ6;L;yy&V{uF4)8XP1mzin{N(i|5W%U zuEMOuy=^(W6D8`qiWRcm#1EB$nGf;IpSOl}3Z|>$I!ed|nyaTXR0bffA%Y%niLfgu zG?&Gd$1(qm;~rAXkOier{6HAAb#qnr{NsZ0>G}-MWbQ&ZjP2El4CPL`jSMA!8P7w|R*kh&#>^~xP>&+Pav>S%H( z@4D4S&iqwM!E4wnLwwXn=JVadWDq!7qpg*Hub=sNlJnN_fSf}AK$bx!pzCTYoY*7l ze|1;QX@c8s6^=yXJ=nnfHrOc9{W1%!26D;v)KNB&rz3AXm8E6IdUZ-|`XG;|_gUw7wA zgW;bzBT?IhJXyJ$B{|3$HCiBiojyFZXR<4eMt?o>?hSHVoiQA48nd@!7wSed_c3C1 z=oG*aq=d=E@R{L~gSuE&X$RTq$d^H@ujM_M{40)T(d15>k-$ABLM8`)7EorzZ~Bew z+n7hpFKHDq$v3B}0&^FAK7{ReIy;`*8Wrd$au(AVgt*nXr5KPymaRF~ARiHcx#KF8 zBHPDznqSbvzIGvG5hLIHU?IOj(cV|vgu>9kHDDM|!tRIG8cZ+JM&YtuY-I#1 z)NO6}kq%>5K=@YkogDdgv@$@{XMA|tEXnVyrfyGHO_fh9<5uHPKGVjY zS!@J}W{gmC@WfgZt`lhRh3kIb`t(p_{(x7ZcH7QmK_Z5PEfV!&=e151f|q$282I?t zaF8k5{D6jfc^ux+;eDn{)m7)X2Y&3C71DI>BO*(t*eGhUCLS)dY6w8wA{+tmkbsii z0|;A&h5$OeP#_(U5SrTzL~jwh2MjVn^VESvEyQ%d7*;5%J&>TKMIER`1_cGbvQ+lK zZG313pKswod%?(E9;K$C6_pMVts~7Z9YCFpMP}!uHswWUsjIHf*kp+n3&(MiZi(g$4=Z z{0>4y8%m6X|NKE|gPI~2!?}o|-xrN-DC!J1Tr=yfr8+Zx)Ha|#Np>_ypNS?_zFP^e zOiUBedIk|Eg?`2cO%$KGAIUeHF@47(Ya<~E^UhW^1vRCKTB+e@y{taThj>X{ zh;^{I%FiZKS-((GNe_AEK{I%+>~LfHI_?cnkwF1A72|Xr7^!p+B>|b0R@Fz=0s$bG zuUbVjiQu3oBWh)hb%(Z=`5?{;&e<94ScuHl-CnKH5^8nnB(ZD>rr$|d+~Ql zmLAp#s+O0^)~S1IHMG3?9?rMxL1v87OOs;(kB-v;g)GjS4h2Ea3W&*?$$h5zp=oAQRq(C3+jT}vmYm)9#GCF`0}^;Xe7uwQXH^+Wz9bX&*~x`BSl$Jz?w!8H zD6^JMM*V1tc5x-QMJm(b+dF@eHEML(chN!y??X)Wk^9h40b{ZjMW@IgT>aRWgPbe- zrMW_bmN5xyd`++sT_cUH`}L4wTa@u^W5JyMGL^i`aE7I4oPjdapFWpm9nXXj_ipOSg9;5ChCG`Z=D*J=6A?j-~{d1$*glG@cudVEFVH`C;CZSLa zJ#?r>*Y&B1h5%Xgs`}XU!xL&jJj-I^?CQj;CrtUhJoe=lomaQM7}D|zQ5*I}2Wmz4 zV&%{IKb;%^?G?{A!zNwk(F8OfVHqH+w|%#)tlbo!@{H|d$WxF^D?MC{NEgPH9k8z6 z7sox(6kd8WZGqST=I4~`8(&s}tsH3)$&q@tDDDK@pg)yB7!WC?l#P)qwU4>K3$6P5 z=DC-U9D*H4nmun9^j5tQ{Di1{ozYj$I36cWz4FZsP|}V`0%~(}juXf)ygRMdpVC-n zrAY7k1N{|Zp2?~kRWIC(cmT#1H=XjMb$8hTq7soVi#bn=cclWY727@f{GEvk-Ozfz zL*^@@?w&*}4@maD6=@XCsW(D)a2lo;Mf1!OE=e1jQyU@aR;BluX>8Xmbnw3JvAJ_K z&>HqadNgA;(Z|lv;#oT@|AknvfAc=VBr>Nv(_~~-HH68HT!~Hq5Ss1vPrp-m=fZSNiBPCmrUt%fg-tIlJ%YQ?ZLzw zZT%{wP5RfreQ<1eiFW0FkZRRbQD{-3m8&(GZ2@mT{z~uDMirJyOtSvNvV87oHmJ6| z&+^CUS^(mv*}+5^YsSMMq5n9~PDz$vz$_wQ7&q!1o6U~DAY(hB>5;agOy3_cdfYtx zzM^uHMR?r}pJnV)-aI#>_)$@p({B8*Y>%bx=Z;?b@wGM<)DefQ(w6tDxyldPT$l1c z52jU3^R~MPuV9&3L}VtbdX&FrpFcT^kg09T|1E`hfqFVcMFfQd?@kN)CWid)T}6HC zIwUBK`lC!wZI#}Ww^NCOj+qrbaXtr!AK2gC3LI~>fN4!OlGl!BeVskTK)XQxE{{hC zC|ZL|&V=uP6vWA$uM#En+ihjH55{!R=}!Thq$F`}5%ON*NtN65*|iZT!mXqI7UOJD zjvpKobnj}nL0<558YWE`x@vP(y5$VU_?p1{mk?z z32}5GPW31pars5oC}wwt@IE&yUt6YBp$HJE>aSsSjOdg%fN1~6R%a?x)CT7wk-;xs zIC~osR#R)@EJJ_vm^O4ffKy_e!%$h6gNC;Oep?@Vb&AaQW^%6&=W02WFXy{-KU}!G zg-9QWI&LR?Lm7vIwa?z+r-9dM&FZ{$VsI&m@;Q5^hxF=n(4EF!4_&?-9CtkJAt^)Z z-O~{)aM;Ia-c!eVu<7$UWeoX;>Ze#bXq+@2C8*_y1q3w8r^F+Gf)OrI)7t#?$+rwP zH@0ZvecC!r+zFBAej*nxH@n!Sy>Jvf-@0P#WZ)dRxzSxut)%gp_Y~vLT;T~o;tZ)>;pPvXuOuWd@=_P#f2dMf zJoN|dK8bQ#_cHxiUTvRAte|Ih;S%dUqPysHf2eTbMQ=(Sd68;+1dI}fAWUT#viNjf z81IT?>USA({f8c*_cF$47VyOJ^fvM`B7Q%8ZAQ&qy2M?6?~>;!IWP}0-2;MglBsJW1rkp|G>`0Qe&F0(=XSJx) z>!HIq2FGRqC^dldDHH1;2qGJcCvY|+$y$tJ>%6!NwEvbmh$`N+>01ne|86j!Y5-`h z<~o#9+PRC={@-h z-uyGbL@AMFZpnd(+rHg3g#=A>GZZc#nVFXO5`Xi<9mttO^;rQlbvi_w^Q_GBb>qvm zvl^8lLhQRUk-4r6WE_YZV@#M{;ooSQ2;s#Ag=pDNfogBW1JTo1%T+GEzc1D*=Kcmv zIWOINO8?%v7VWNKIHRx~Gh{VHi%ih-ZapDdX-`nwogv?z=0L7}#A@PXST^;YJ1^r& z-liA@!CZ7%{1?zDLm=c$gu*GebfF(jW_rf0BPjOj)MS$uk8BPC5UF)1`Vy^zg zyf7U0E82qxkFCL_;W@e6!)@m7Fj$dQ*2^c;fXLQp!b*nmpo9rK8U7Vj^hYa=%4B8+ zi1Amnvc6ZswnZ}poAJqAv`iwo=(l21z48aJip z{7^8mW6dK~W^D7cge!i`%!t#mDB&2>)NZ$s(XJNW>7YxAqyMymt643b9Cu++av`TI zZzP>ubn$n<_r~_w3xj5Pl&I)ph;%1b{!Y638%adDcGDd9r3~`BZlmgvOd$F=OO<9m_JN~$G zbV4`rD!Qfecx*8B$P-pd&qT`q1yho2gog;?7UXWJ(gLXfSh)GQIr+GG_*po)7&ti@ zm{2)XoIc5#x?6x5Wrevpxdgem{;L9|*9LVE^PqCb+qk;9gN6A2#|l^A6}{^9078+0 ziW7YcPUmS&y7?#YOzqd-bO7^UaQ9GMsDBoa3SXg?=xoHyE8u&N8c|LuMYr!OhPfPZ zqu{^^%~GZ9MbZ1iW+$emTXO;|o7t2zuz}}LsAD!cmJiF?%Hn)s3(8+3--3GjFKf&n zteKoP%Z3E_#993wnfxFz3(MK(bdaxwzt0N4?w@#%eqAj3=CC>KCVKa#=~`g4*zeEr zLGk&i!1*u!2}-IsCx?RwPgwW-XHO=x#U_|y3+r!aN=sHzk13Anfzxf8-3>UEtz~|_ z^eY1Cw1Vwdn;XgNiAq0gswkvJyroKgEGkKo`^3&R%S-C!wlbsMbDF2$^*)f;sS&N; zN=o}O%Q}r)xT4KSVO|CYE+W~fXfM}{_d+_KoEF7C{vLp5Si&cnEPuOM2>B#t@-6pcI|9G zb({~eBG86QO?|+Yi(YfBb}k>Zs`toMx=bF6kFVo(9dgB$OyMYqhd~;;1`^=dJW7@Q zhdD>K>dat;DEitc`1)9FF`M7*W_7%EHjAt96okkCvkihH&lV2gJK z9-?3csLlVt{kC@`Kp|7ZQKd?b=3V;+iwfP_teT1yW>Zfq3L!n)_LNlzQGP|#EO1i( z(`acm`3hNq7s_`B#ceZ zlApCwc6|>i^1l>QSU=fmHa`BBsU7Em5=pn-Er$!<4W>VWN^KjavB6kJk3opWpu1^jC=^&);-M32!=b)F{?4{k2Rey6j*wa>`qJA_ zA&?d;rf9q^4W)`e_g5`7Zx4v4`9u7@M2>6q9 z2f5cFg%++)qa)tr+QzX58SbbqQGpns&A^jO`SGs_;;#=s&@l_+#)DW-_nu2SDt1|J z0Pg$;peRdE{MXc|CGU#gSqJ%9`tkeLXh27YZO>T`o?1cl3`!Bs^EYkM@bJ$S@}|_V zau>byux@0@T>!Q*B3z*lLMW(wwo_VFm*HLA8#EPnIyn!15V!F-q?NbD_%?yOM)fW2 zPzB!1_p^gAUffP$>bOs(;Ypyk6>092L6anJ$GG9Z6D-6`#y;0(PVA7zkCHa2NMJ8* zS<{_rhl~CfU$419n8Y={!x1jnftP)wb=mr(q}nu^ zWMeeTv9A(MB?tIj?|g!N;+W`}2t1LM3um(nkMNd-)eJ!d5F@r%DKG02uO#7L2%*Vq183B5!xB#z;AP#nUElRSgKR9+f_Y1t18sBn z9`!8&Z?PHYT~ftTn)N{B%}=bjf4lI{aWD z&lX%znG0O+FG08#4`6k&$#?FRo)5lyiZ_Dxqj!HXqEWs@-s_ z#^_K@ci#8oAhVR<#!Kq?X7P~jx;ur#9>87K>}HB?34=J{oLCraN4o`Y4MGKZLhm?HC^XyCrnzsgH9 zL|zTWxW0b#Oj88=)B>1r8?67el8%d|iTtKSi#B}JS(s0gk*Y+CiZ(S665bnp;quz< zV!D{?SU7NcR%u4afS?9X__#B)<o2$s$gW-V$`d4i6W}{?ZsxGD4UNHK-j6=ABCF zlw0%D7U@^DXqWST3Wi%pN>8M?PZoKIYs?g7YA{Ah+soxyqH4S0+ZO*+OqQO&XC7nx z^)Ao$RS#bbYA#$sVpvWR?#ejm@T$St5}cVQEHa;UX8jtkLE4*9pBjETdv7>FL5E3= z8rezx-hE((pl$LQqSq#UYX(F8J=51tAg1=@W0o_f9g9E%&!!q-!_X8c^04ewX`biC z#cEEi6t2yBC%QgfF{e|Hz+$}5i&h~Qg=`8yI|o-9QrfRr67D+BfQ;Svt~;Gg^Sv!vZH-JC<;A!>Sl?@gK`AEi!=WCJlg?L7)!~XQ&O7Z`^C%NT;h@}7Psl^+dU9? z^rynO=jCZ#TrBX`{Sb+(AYpHA5mIyaxUpsGzHZd+RAJn_+CBHOI^BAgJ*<7hd(wQf z?kO&@4LLV?`MddaEYi-=b$6>tg5@FFxEIMQs`O{>#wI~Qs-T8<^DS*W@1{2)+ACHn zjUsbRm!R%!T(vy54Lmh1GD+>Ivw~58oTab@RlpBqX?bk!kVHT^I;61cUiOhNOgR51 zPIx?{drym?PS7O;aON2#&>dMVw7sj=6v ze_D!T%2B}gku{}7B`aM%8@X(9opVHo#)0kOO=*$Ia+jS)mJdtqI==Aw%WlvDp}GzR z0(b`-^M5i_jRSu@JaPihaNtT#%%u%$D5zxA<>4&g)rYZDVB?!_=H`~$5H#vuK#36U ze0JJ{i_Fr!gn+9{F4AJFNzqEk%hW4C9V{UshZ1ss6)AuPiH_T(ZLU8#`5Ng2dAOYI zFlK+#lg=*U;rnJBs{8zS*pox~e12}jdpcZ0^>TGNJHqiAK(pJDBk}B(5ZNQ`k;VjvSxJ`)8)EA;-gtIsXS19kZXqQ&4fMCH)3@wEWI z#>w+S^FD#_9R<0-oM25<4n;>xr+%s7pDv_uQaC| zudKWrue3b3w3MJY`2Vf)TH}9#HU))*{&j?ueo>*+SH&Wr9m8YVhPk+VG6Bo=3vpE}H^;4LI zm?C!a+)PftOXrh^46GUqEOCyks<=6!@AZqiwTyT1XJMhe$>ePsT4fmsul>Ht@5X^a zG>~-uQD9{iZJ?-je3jg73IjTT>h^bBjOQat#rV+QY|`oozTM`perBzN;yeqPe)fV0 zhr@0jRc#6pho+%zOm0{h0{z9&mYYk6@7%D^1qN=-RnT322MkozPOP%K-JrJA4Y zz7)1~M6ex&8J1-{UJKTfK!?+xnz(jf!2K)9ne=3v)-5Zly^4ZXj#Nh~6Eg`eKcFx6 zAVLVXnm88G2F=HiF=vG8f#>t}C&$O%70we757JGImJNAZokydOu6X&_Em{p1TI0Wi z8D-z!1lsC6>10Lq%X8!CeqA+ZR5kx#nc`=dM5)x&h_iS4ih(9)fcIc z@A?DD)N9rOVTULSc!lfVGRJa8hF(J_)XUeg><^ZHp*2cmWp>nTnkijrNGM&EuV_Ka zOWv!MiHqi{O=UgX+h)JKTUD;k{uq!&ud7y;E%U^O?GF*+tLcssX`Nq3?7sB>6aCAs zDVtd=z}IlaVCJ5o?CzHT#6oo{D_cm+&A0qAEq87CmqDX%g}zh9;W{22@F_hr2fgb- zZI|>dCm@*wt+StA3G`e`@|R1GmXVb8Tbcu7BNL~ z!@t#{c@9u6q9JXNe_na6;Mih9f^m`u7dWHG51_j zk6bI+C4*2XP;JoqYhEjt-97wPb^pAtX&d;W!1YOSBrcweLO?j!b5`?j6+TqG=quXi zed1}Zd~?~6DE4l2lIbDcT>lOTLD^k_!g)|C_PWpK{mrlOIEMZ`TqS?2=FfAtq!?}; z(cU(Zk)1QdZfbnm_x`DoTOg?r91r{*m}t<#!S{*`;(|o``ir z@l~}0Wl!_(x21E&3fKRSq(G9WhRTJ1vn>@dv*+GYG#uJs1EPk+BT-=44&Ji!Nwg9| zzLQS>(*!G@Qq}ikG6eqgG87C?Lp8%F)C(kKcaiH+)FkDX72)}lfV=r~((|bvGAL(0 z_x~WJ9(J{f1pXlk!i>>S=Dv1jz87C=)t|2#!z`F2wy$8Z@E_j)LzKT9Oe{)2mtvmh z)5S0^3kT}n-PDXELk(>~#E_2(CA$*c_-dw#7XKmok4?MpLtd$E&Smy#!FaGswDi2D zuCV@>208Y# zwW3YIR7oK_L!gts0B<-f7)}^iZG%blZxWS$_gkB-^`R~f7(r)*z!~9MpWiJURWLYo z1u+Eu6(1d`zbS=1fI;=UKXFCLpVvA4< zWaLjYLHub?-14*Sjq1C?%SS&KUOdbH-DL>1*o1v%dO&4U64pq9T3j7SpRFFq4#txn z;!#V<-z&ce|J4-DKHQ;}Vza~vO~jPwC_=23=(;aZ5Dp23O&&q(j33|UA_!oB;b%qg zI1^6x`Lx0j!EirDus9P`_j$Ae1Ym@#5hBh+|LqUa2!=EK>^?Vd3=Y%Po)!qXO;?b> ze|tj;az8XAcW?2p_Y6rMzmMquXM+5vLPaR@v$hge57k^($_%t10~O)_O);%#2%{_} zvR?xK51n`9JAnJ(ZTX~dLmSWz0!K{v8E`j;TE;zIziAd zPY6L}1fPjS<<&!dQ^#C&=#>em@;CBV6Q0FYyOt2P*71DnougDs)_OW6AM4GlU~DC2+|DsI78Xm>0LRt0`~l zSYFPvbx>`hq7Kx)-=_VOP$&^Y1pMbC>G|#bYu>Ep{c6G67fB@v0UkJK%|#z4qGbMFT@wIkR%^04AWAXVxdybAZn<(GYA8DjP~CIb#w-iL4%w@@VFO;ymz-1 hTkm@=OD0|bZw)-=pqb7fDpY=6E>wDYIW>9I{{{P4A$ieiZ^%HWIjwX^|9e}(vuSeb*nejc>;L`<_PL|w_E9k3i27azu+}?6Jgzz}Z zMAv2dRl4p;+WhHYGz}=(N*BQ3Mhb`{QG{Qr^z2$om%*CNP9r$GB5qq8#SBElUh5W5 z!`?cT@dc1?kjuvLj_Ar^4V5CNEK-X%sAn;p-$g?Za6kPc{8cbQpmZ|y(adkzITC%` zot8ORJFA8@bACfr$k-gvIf~;GPlW_vr`;U!-vmxH^187}$8antFL6Os%k> zS_+Y5j?t}Yn)G~Q8A`K^DM}RcJLL*)pR!kH>R)@ZY`tlwCEL?@R}myEB=schva_+c zQy$4tsM%O#QikUF32`WtwH*BEiObKXED>$vG--lGEr#G3AoLm7b#C4XONeai)Oe&# z%B#E3fIP)aBS=#Z3(eM}+qSS;{_xJf?7=Ujvll zds!kGkyN_mu1b59!o)4OK^GX>_hAs(77f-Kktvw6i<_;SV}K0^7`#vP9$&N^$B~+8 zVBz)$_%7HA2=A<i|xbM=4YH1Vx538it{d+$NxP<_ zkkxKS!{p#ukt+b%>xxE1o!Lk`P<<3L0uu_TdPQA9h$j$lLVRQ!aYC5AVwgyN=Mtli zp_@anQ*b{~6WpjQ?FXVljWVVFMr%q_oC2tR?keTVbBQLAE0;`ALRGs%(x~EY^NJPX zBqgBF2}aVTfKBYmxuG?rRh*NAy?z5)j9H4+S9FoCmT<%_=I$t}a+T1Wg(1T^#s%#j zU(cw59AqD22G@d0vooj?5^i3s+ZtRAf4|w?@9RmTfljhqE@e@My`D=#3WEoez@cU2P!0%Jk3~ zQN^?a2;*;Q^!Bb^BF-0luL8%*HrwhSzTkbdpn4}aVLoRr417z*e`?Ea+~zRhduQ6e zekv8&G|{~zKXp4STq5}*hoar0f~k{0e(u@>Zhr54@81VrGE1GG_g*9x*o7px^=?*x zF7B}3PrkCEe%yB;eH=W1XErhyUp(epY}Em7cf2g@t5*zcLtm1kRIiYaV>)rYTTKjo zP9RmiMq39*(GsIstK}Yyo4l&|kx?WT)~b(GR64(b(xb~PB3`Vy4fIm`tU1f{6&SHo z#z*gk#gu%GVoq*s-`{p4xSVNuYatXsgWbfvz32|<$`ZIgy1LdXGwE3vr>!-uH6F$!t zPWyREqmA2}#l=pT@#>{*tA)ji&z9&YyW1v8`=_;s2)PTHc`I7|dZ?ED03C;MvP+2O z#t$mafS-9;7>bkFYbjpUAjY5v3#$kh*m!>~z}`GY}9TcrM+WE|*76Bb)`rgt6&Mjcp{-@X z>IwRLcCI6l0e^qKuVjPtvJ7W+=mhw{uoshZZM=i|X_oQpOHzlLKx`|TyID??jMG!y zs}ZA!!y$kG!*JZlHVRtFGR8K6!5=WNW!@Hs7JCaXC&oXy-wdm1-^jM*F1*{gajor0 z8DqH$h<)f}O5KqwzTAW~iLNgI7CUZNbIzT^G#&Q5CokBX{TYrecZco_@IV=^)2XQuDtwQ$|1VH$|EWK$p<-00*L;)PyA(2nZqA zZJUy%OtUiCh>r}WqzO~uS4Foz1sV9}Qv3U3O4(nuJ&2K$7`DD$TsF&qdC8!7T}dp} z&t~Y5c7Q=5vN|+fb3V2(`Vyl$VE-~0^6V&yXOb@)#dKlrqWL42jmeT|rKOuzJ1vzQ z_|uq(2{pl?9_3Gt#UId?gk&eA*9hzbAY?t_b~eRfCSu_k1_c})_Uaew_a|@4`5$+e z;@#1P<-qgr(jVFRp~^tW2Tp%5bo+*naArIGZoQ|&mrnbc#FD35-r- zU>1w77{}fBf*D!k4=G60fo2zLEv|haz|q&sIo3Z+xRToD3J4m|GQMmcb3Of~(hFuZ zkwJq& zB4I}chQYUll}yIQYB34HB}&~$iF^gQwT+Nb&7(*RJ!80`#*rU@Q@V+E=c1nDn~2}56MVI91Z?A|9B+t~ zI#7gzffwcZj27e<8=Hj&hXj|Nq_uO4xZt7bw=9I~;pLEQ*#H3(RfU=SZ6iTxKu+ZE z2f}87I;+36U-on4!~3PSS{>q&@?53hF*(9i{_;m*<$_9ynEB5O1^U5g!yC4_$Cbac z(Gg;iU^pi?O2ZSZFI}6I{zM_Q9yE$)@Dk3f}lamBMcLArRB->RjUG`S@ z{mrB-8Jxb2{!N3qnzJXON2xVkRLWu zZ$D-BhXfh=E2y(5M6jXMH_revk-f#`4@D~u&ouDmO@C!Rt8^oGR*y}-Dy>_>^ajm` zPFWz{u(ZYr^eJ1AlMz4j^Az8;Ct~j@Hoe!Zi^?TVl_+&jFdm@ul`wb^qnWNNWyvz+ z{uKENteeadAC&8|iD>VVgUH5~xtrNui40Cp=|=hE5;tO5XhB?V7+SKK!pb8q2lriH z9uCB#C%TWlBjVK-ilYWqN-Hl(@Xk_Gw!J4!>`CuaT{x}v%CK{C>`C9~M)Mfe*o7Tj z(!mZ;Sb>Z^vIl1){aT^SooLtd{m{l#?D4(_T|nGcsDoXk`>pz+B7vFi-uv(hf!Vr^ zc;TT|#$U+G99?u7=(d+XsNw6VVevN<{sy%-B`;9MXV7{cO2>R{N`uVjy3}7mlM z7^B52Vu_%$pUMMkD#Z#rIqhX{%rwc)W|voe-dR7@o{Ay@x|+EQgF{N@VN$cagSk$5 z*B{hu0<}@Y6t5nkBwo+#=$kD%5UEj2c&AJzB?pcDlajh#7#a8E7Kt8)KI*sgHbDUC zB=NqKUJ?LCiW4*d8=Q$LA#auSKP#i&BKf)L!G@_~R!feV9m!6>pvX`N{yR z>0LtRb!$( zqT}s^TN}GJde@k}_&1YJM#$RFOtm)Y+w-xhjRC8Q@#RfL%nAMtpUiiVH^&Pv$u-3} z+BAnW*KO@p(Anq*)wvkc*KB`iY0sOoOeG%!L`%`;#r_hUeZ_!}4aJ34Ik|G~G!?GV zp^iyZVT5I)hveP0y9soMh}YFK|FR*!vdmX7lzpJ4f+X%mN4 z9K0L&PGsoGpQ$=dJyS0bA>&*@#b!swi*cEXpuK@WFQU@pK91z~8u>cY%D)`TJ3oNa z+mll^%GHVp7sul+(pdR^w}*j13egZ-xbJk=_mx!*gq@7H7emO^NV^AuSI_WUCm9Oh ztTThi%SQ%G9v_fX5&Dh6T3bJvD4id*uEz(i4aSI$KZ<3^aYH-yvG2ZrKR# zrboGf3taXB`<|z_=_F#o@~mawit+mYx|iy&w9+;&1sfh3WfvM;n3~jQ{jR|*C#JjW zLyja9&?=3`mjNRIiKFH9#&-9V4D)_7vcB=;FOZwz0%IZ>o+68t*I*#$+Wl1e#08sF z3sGbFWBeNOGON~KvN~|Fx*6!H4(L6P0`QKiKNbzuXD?8y`P6dEGR&noVex-EA)5ia zhKDmi22`pz$J4t=7^5S;oIcDkJ5{aqkmg1wevX#1pdtl;#MA1u;@CD&ZjuMh3Ggev z5clL3`rp1VU*%LvK)*X+sD^k1dUd+*)W4|qI@t=1I5T8y1zM>i0uFFVas^{kq`}Vj zA!|l41dAL~Ax--OGc&4LNR{^1k8G%>5Srqy7Z{dR)VsZ*!W>SG^s?w9>+gO! z5VvytuWey5gRpE#spsqw#Sq5ZDhbi~O@-m(o2wY z@JCcfS#-R)fl#-I6lvd6kP~^+S}=wDqiz>zr*@4&%?X;%tJF4&UI-CSC`T1XqIJJ+ zrlz%~qjv30^nTL2H0cSPQ_%aN?cDp{pBF8kwYJ%;=#Q?QZ|zm~4?2M-15{iySB3`1xQDVdH++86ZJc@9r_9KKG*&bp8y{qEzuygPYfNA$BUgvuvItnIB;>p4l$9DFyZR`9n-{j-?qgHY7|2H!Kg{jM1`>OxcDm@iB5Yhv?HW zq9n_Dw#Zlt5~`Pc`HTM!^QVr4qv*lt*XjA!5hN|ASRmV{r05JHHwU~aOL-c7R8lJ+ z+R8!fB-TbHhKkAfC-l=d7oY!Yk-G>0Ob8Zc_J2&}J80a#j|o-m=`&o5Qki*gbl$DW zhottq2MitQxnLoul@)5Y0Rl#8Qk&tA^pMMS7c^ww8dL@Oi7i@$#)=+tu8V*rvoX9Cvg5_`E*F% zmL+OeNYtL$48X_AnjBm8#SHCKE)3~6p*9iaA7U2CWaivuKE_ALlky`+QY-3zlzH&8 z=j;WRnQ{FUrSYRDeXx_#M9g$|x<0xTKL<%To8`zBBmM@fXi-!A-#)=vI8$m(0hrAn zNB{&V0DFRwF;+7X20$JRH&T{uwM?hkLEV^GNsvK|Ba$JJX_kf7TYgZ^B{ z{m#DDmW9ReT|beG90O8VJ(+I9KSxo*u)7>J2P&o48nKFeP!d#C6w2J1ZfA-k!X^ZiJZI~RSG0pJ8t@CEck(Td zFm+@S0;0C2O8bNHW!@--YYMXUs>fR~QCW{>p>NU(BPZ0Vz9)cVOBvoIX)ZuIV@^CK z0&Cz9^HPD)yI|h~0l^N}2E~r3vtSyq&@R4fh=;JfhQa3SS4?cI85y}D2q16puQ)Dc zW*IypmE-)0JeA-+T_!R`%@Igyy3kl-64f#|Ma={_rbcs&fkIR{MOgo8nP5dZYKC5u zEMc+mLnb5!H1EoA)Pz())Uvd2OsP?GV2yB|aNf2Q7Cb#1ri~0V?dOnit4e{?SZIj( zI9|ZcwJPEioPRGKyi9E~6G#PylLxs*qn?u}KPt(QCC2C@6Bj^-CR~f>JaL^vdOu+e z&Xa5iu8+emM3VaJ20Wwwhl#o582IE0b|{;Psc`WKbQNq@K6{JyqNX5D`V;%B%X zUTGIw5(wanI5>oF2SKl#>3vx{HMZ&JFjfU$Sf#%Hym{O`KRHd{sfAlBbS_l!KD3Q; z&nlQ+=g?RVexAgdH5=_Z51mgX`>yP;u((TJ+pKHn6p08|l7lS~-;v0!5fQ`vJ^znl zRR0^j>R;d`+`A9iw>>w}vx-n!J2AFkPc%X&(=tAzH#?_gWKc&BK7F*v13<~jiF{!k z@hxhAP1>Xx|T$cWJpc>HLOn0!0q`1F3rGsv-< zVt7Mw_|j&aG8{6|^jJId)HjOew7C;bh|}zBRHcuWdE~Op=x5ilv2unR6wh4EG>`c# znWTWs+h@n=Iau9?6|>(^N)Wl0v8)atWsh2ZG@u&{0qG5ICSp9qt>KnZS+%1S6Dc&W z;}vfbTC7kSB+&jORl7^j!WwDO@@m1A#1FaZ>$l^b3r1>SUIC@ z{yAYe1i8Zf!VggL;d4#Nty42dztk}pyF0ZRh|^2(Syn^Ekgt*0{k?ezUWM8|l?rEJ zk#XJ@FWc&)5d~*~m!fRt9LQ>Ow8FEKFKT*S5$uwQ-F#=ADc#ISjp9Q!y2hu|RTU+iJt42}$bG;Y_FJLX(dq z8?m!}dk|W}^M=&#VS4W?pEJPY__wBipQM&lc7W{DxbhLjTxk0r;xuPGDu;ylaIo{S zW;z<2fE*)&Kl9QfcJ^C#pgs}~-t;|ooJZS3jA-hY_|+{6R|996jqd$F-bg7VOaKgU zCa(W^IXE4F1rnT@>;HQHKdkWr`Oo|Rb9s#)0Aa`k5_HVwN-lsd0Kl2D&G#=o5b*#| z0pM(0%}l(2Y5?Fz^S>x5;9tw(zcttbfb##=_fk-$oQMFBz}Y!cNPhmy4>B?9BS>9O z)g>m*r3_u+YQD8S{M+P$;B<@pcd9W|b-o1V(#k6H z8sri0n(;XD6rOPf%$C*^3ybJV!&Wl3iJ8*qmAEug5pfC5kuBvzC8N?CoLY5KRg?&= zyQT8Z^sPHFGS-y1G>t@LpkfAQ>C@;qUZuPiL$KT?ry(q4Q$)%2-CQbkYG)eG5+}j1 zh5?1}0MuZ477GGFh05#>N_aMgNQk5;1WXQit>d#nN3gUiPDS1_cUj`HRN8rJio@u& zB#iO_EI%{hT5DrQr$Ka%o2Y)U*g>p-1y~e2X6q4dbpmb4!=|DA6qb}&b zee)hIT)gP@{yT|~v6UeUM)I=S6kzJo)&Lmb4(xI1b*Ou4oAn&>IA>KKM>qs$kk|Sp z9LL}V{kj@^^ikT+RoTor zy_!RZ(^aY4#P}K}NY4rNCXnaa^d2kSK&-I@nzci+}M7+ z+Y)Dtf@FHn`Ui@pWo_AYUoQ?0uvGPAb=hhlu{L6O#qs_`&knT=|3=v@aH#jWdm-ld z`;r4{eSb24+gNy*Za;&Q_H6#xdsJAvVzlIjyC!C`ah}GK9gcK~iiOq!n8>Pgah$}y zxz(*^G<@_gtd&Fl`nv4z-UM~5=vjREXgcEIf+$=4UDL25bJZ7|ujT6fGjr>iJcMvJ z>PXTfb+WbnceRAL<+Lw(9gtq&nMw|UBNDi}tSz^6h&rg^3AVty+)XaYTexJuk|`aL zln?-dY3wHkV&bl{8Me3{`p|DP%kQB2FK=$zg9iNF95Wl|8aCqa&z5XV6ebqN`J${QD8Zk*^KE<_*{29qV#6Hwz z+Gt8ukjt+o6V1m~Pz1e;y?~y0I7@Jiwv+O+mvpd^1Z`IJJKlJ7TrA>Uj5gd?C4@ib z{BL-RWijF8Ml*Ez#j^~emO8r1? z{Pz&&Df^FXsK0i`G_F538>C;O!N|xp#PI_nB*VDKHZ(G*uZQq3jyoXF z2MW>BX2ih{9_(v7V$q#{B&Lbl z!A5jmaXHW}FAaz&F{beiui;@v2>bdIRjX>#P)qn5-ZMR@vZk^nR3;LmMtBgt;+h_X zB0LdX$>BZP1eQEq*ye4An1g35Bj|f zl{Yr2zUzwo4Jum3e@65q(sb~c9+qJGQ2Ju2kmI$5%UH@VlU@ zsbG)4V66W(*Q{4p$+aID^a`a$s#*j3&6EWpnWi7r%owimoc6gy60qU;3x9%Hg)=D` zs`q#agh)^aU&3GJ=FMi8*YiQb?Dq-y}h=hHv`z*7?cNsGqCw3`UrMPz#FsZi*0mpk5IHgIAX-IGQDuHn654 z%gB7+z>_{oH&zCjsXf>vj=~ay2+{=UUA)mSvW``L)kk221#m#3#3&>nZ-&YzzFKb{ z|3$#`6N4P!R#tBW3-T`g-bzL*=KV}!Nk4N34k=u4I*$p3(c+fYb!{oRdhFw@R-szzfn1G|sx;Dwo9^hEpbgR9(G}*=Mh)ueKQS z-=K?@`}A?ZzY+c96S54X99TqxnS+0I42J>lrqx@5gB5~U-?iBpi8O3h>Mr6looBTE z?#FrkzRW7R!g=c*{%Dh|MI`i&6Sf8aoWKl?nUIHv*^DIzXo3PT{jVz8QU;ts0e<|e ziYQUIn7QB?WzFm@TrGhtT&xMb^faJO9lZ$MVKko{gV~r-83mB)PYpk&Wo&71I9M4J zsX!u3PdG~RCCTrOpFUHqDy;47vxFp<`myt@KaQLIgPuebK6T`L325IXjfP`!;W?;NU$2OV0xL zt4gQGM#+9AM5D0&%*iy7qSaq-qq3SqrlgR{(NwiYr`J@~j`t(JlS;#|2_wJh<4SK3 z3^wA^yQg5aV$>9-D>W3tP$&cSqd>QCBOF@FNv9Ukm!eF}W{W#j6vm79kK^h8y6@#8 zLvor*vqGfq$*o{+g*vrLJ@ZS?3eo|)m>#3=0ZkvyK#R)mU?WPY+yo-Yxo{@;^d;aM zn-raljiM?c+8`Ze3r#0z_v0_$+6Oy$e<|HeL$<)lZRePZn+e<0V2przaH?l=Ceu1@ zzG{&eR1fb13&(na<1j&Z731(`4g1lZEN3;f!b}Z)bB4dn!xgfmA-c2!wFAWF^QSzS zI$26N0xov2UVAf>Pv;3D%NC^czy(SH(KxURw%*z+-JL#G8ri9naHDH z^k~95n9j`UAo9NbTXzK#R9d@DUw&UjupJwBP7Iu;ogT?2mb{z~#L33Lcn`FA!}Z3# zeGT+J;yT-0+gYjazj*+GTBU{^92~ALQHC{gK7V$5f1N2be{m6Xx4&KQO@?qlSu}U> zeZD-W>^(W0-X1uZq)4GS2VGZm*Cb~u@`3Zi#aU!4%$&X zu$fk^HuE21G?S`gG>>28_abMFd5sE}c%ps`VVlG#8PDU2=p%U2?+>>BUCJ7YT@ukp z@#Nco`2PeIiGpx;ATOLJ`Yrjs)JQ_?zW}yyc5ufs=ik_35(Sa$U|uB8Z?|mwRw)O% z00vNftOd!maCQ(cf+zMZ-M-ey{{kY}A-pJ_M7O;Ao+A-|g_j0y+$FYcIz=lf7w1YN^RJ0~1{Ib~1ZvSjS6tFifWZsrm7vo4RanS(bHW(Gk^|+nsdUS99{DLK z(Ui#8XHQh+95B&Rt$j4u_m0Q9XF*XR9*u9CSI^*Xpk|r1 z8&fJnptUfg|FV(~)BuJd^>PB}1y-an^4r-RuIttC4qBtye>$3ER)*6QIF$D4s8m!QEstxcQPH;Z> zFDJ2JL$qL>dRPp-9%KykL>*>Ja8o1`ly8}%fnCmpVQ6ZW6Miqc8R;g7A7$ChMWT+! z9o%o-Ij!>6CRIq%c|oJ~ShkwHUQ6zR`X7igwOPU~v{T>QAkt)YCY<|( z4U3YD8m`nXdk9uUTvLNVB4pGql<(#uNWssw;Kt(@Oo_O*t;YD?OmT`Gre%&qP3e-$ z$++Cs*>Gqd(j#Pv z7y;lCghgtoGRP>MsC4+c=hJZuL!!o)| z;pU=n-uc`ELl@wWI2~y{m&hf71Kqi5OB}M~+{W%!^ho>EL2Ay z$O|b2MYh!w#j3D2cO3(gUNk39o0j^~`-aH)YM2bhPlqrJ4IduBgcQ*fa^6b(=xr0Z zEMU)7S)6qPn3|_em-7PQ^Ld~vE%z?^_^ll=e-z;$D*FN+hSU%jA^GmXeP*;s z>sbxs;(h2r%^UMlV^)k)xa8a~OH31XWa<@Y21Rnl4X7Kuu0!b9W7eLor`LO zw3OBg3e>K=h#uzi0Y%h?G;IwnXP!*-N5!WV1j@wvGv^OJ?mC@kdUDlHI{JAZc`9Z$ z{a)5T*)F{^*!sS8kIP5Od*I;mF2*+qusU8PZ@Sh@4km*eiYgPmlTtRRF& z!!EAzW0RD$FW_?>YG$VK>6k+X)o>rlBflXUx0;lr06CkQ5{98e=j1!z`r68=dvL9u zwT8b*n2z6tdDUlWKMm%>aw1U-uO^FMG8p{<^^>$-FE(1RH1Txo_ni>Qkh$kTcmaAp z`#pMQv>+FJrjDRQNb0Wv5RW5nZGrqEOmpyzu(3-oI5`tXCrBWw16tybue%9irE!o5 z_m_6|OBnils>LPM;`P$?#K!>2AtQRGc$kt20rM2@^qm6Zey_@twuvosaL2b>>k)($ zM-u=}N{Flw#9p6xx|x+Gh=OdpsLA>Zv;8m=cE#vf)#=QBKWEv+UF&+g z*4cn`!RQ~`I3rQ&*8WISZ8*)R1+asw?^#9lL>^M@{<#hcjVjn9Y@@lWG<_4xDOT=& zsIu)gsD~Km5JS)gZkw>*%tC&?%Ii2m_ZsLN#|Q#nns3B_pD>@SIClTdPJuJArvT*s zYo~Ft{>KGrKp8qN8JxJmS0CS9;aHIt@SIi#mmB(*p{XXmjTm>dzdU^h z)G|9o5{xsi<7S{8dOl>ig27&bL23lt&2E2Cp!K-$Mswj#`bPN41c~s0ivwC3cMX$+ z_J9-Ttmp7Hsq!gKsr!4p(h2Sdtr?C)(Ktpg5IlXKpdYU+&z#@h`2=q%QFCtHLM`4Ytdh3sTiKzXEeAeeHw3*ihkUzC z-3kx^-=>;2D7Ziq{bJ1((*}NzLyrbS2~2N3AU6#8zjU#YutK$bD6y;4b)K`U2_+Vc ztDBLq`zM^fU6@|nG#v#1nBN-_h(`|7%z(E@pU$gYSuKS zlG8hI%KwIxcdk3St#WnFlD^2? zKt+OuGsM$J#mXzfDdJK@=D)MC2UqxAXsp~@cgjw7HXA1`n3qDc;C)OHEDI^na0>W7 zL)e2BVem;zqikbFst11#EBWh2dB4Xpyh|m%B`6Ml>SYw$Rv!>7$JyK?$QceJo?|NZsGJSk+Svi_2U%;l*i@ZL~(B3k+xLpXCn z*%_8(h3glas3Z!Ie7{AVe|bdIgmCns47t;a@Sc_^YR7OqcTiH!4tlv9rq}X`6QrVY zdnZ(cmXwO``^(w&Xt)1`H|x_Zv~uv}$*ld9VQq#kLn#Bfy9){*M7Wl-anU@kAikoT zV4D+6X#TdU*EBtR-h7B=NJ^jp>^X31bSltdkgqY!x0iaP+l-G&EnDhS?R?ZWo8v=h zO0=>ri&-Pot}K07Ah6tFoTEd50113w6h31Gb)<_rXn9p1>}`}knTwv-vL?H#E50$z6J7s%q2{8;v}y8BcpbVOH``*nKX_g%sVr0>Sk9@*t3@^+@~8{~ zz2Qn=zpISmCy)WFNVjBXV37uj3wXxoS~Od9E3Ej=`v~z;ep2tTk2FCIyOmn4RNQXM7R7=1aQp2x|{()^T~LF&uP zxu<`8-@4!|+mz7#_;r%lG&g zPDMRSLGoTysggn-cCz-7g39oO3|CnJqx=cy4&qcR+$#MADF2SPyDGNdk~nc*ZQbfz zYx$M=1~$b5 zr9QYX(Dnl(oqt^}nl1CfqwG-!fcvs>D}vRcuQK(}N7GbLCTxFMkIMSakf!mF>nNxP z5XYD*0as+|E@RLA7odaNDO11$aks;BLVh_T$ikoKBar`+*^KNb^MvgArN9s0jaP~- z%V{m8mai+0bzE%-dMqpD7L2kkT@2pQl#24-!Q#Hu?Cq&L%Vn`CP=^+{ET#FOE@8b` zL-4-ly=*4vQz-<3ptbk=nvSbfNn56d9dg!|BZ+0MDa;G#uLUu@w-lEo5yxOw?(I?2 zwB3)x_7Xun_pExI^k5{n!FS(47H9$!7x;j9@E1{I=kZ=3Mf&GP30pV69PT(Lk#vZA z%E<6b&CA?;=K4foIrn8@G}#|Djmi~Q%1+;#+@;~VX>Ce(L{wP50FF`kY59&1r6fJYGS_qTi)LNRI_H~6daclBd_WWJpw z{*?l~Y`%6~gO8`;5Z8~}jrL)bl(XjU_p|=Tqwde^OM#R#jhL%$kjGbBPuzIMSxz;m z_4kK%lYnm37H`K#tiH))nsk*|oyqK+bP-FLWUw7*r=9U{y~W9^UEAl$&4NiAzXIs_ zq#Yz+S}Rb**wwO~b0^qi<(x!?y2IN2P|RhEIJh|Bi?0~ zIgeo+4{Vq%Csc(cgQN2@47N=-QlElqVB-3B6S*L%851^l&R`rEN_XUvob}xP5a7Z?MxgDy16JSTWV{DTSi%`a0z!NA@dn2A)5-bB(!#;#u7*1L#x(Cug zu#km6sAa_>u>f~Sr8W_2vVhO3m2gjO=^hM6_KCmBUO{oIq|?XoL86tt7>Z^P&MSacLn1KbmX|a1ERKG5Q4A*U0=xv-!JmdE-IFR= zW}66?RO|gC`Dm3&hYf9cpwvW0bs6ke>uR&M-Zw^b{1Z_KGR(FtLXd5mV|bkj7#+N@ z<+mfMuT^N*7+VHxhK`tt9zDYrsu(1#r<1)CcXkXJ0U*i99YepCvXel?Yy1SIcO!Q)7j8?uPoau9r0_!ldf)gy&F!TY}|w(d&EAV1{l0 zD14V1OKc`~kik3TUp>G9`tFGjSyo8Vx*1RM!6l_b2><}%{gmKY{sM^NWauzq#0x1- zxAr&8=-~%>c~Q*-L_{Kn(1?DZ;lg|kP1P^6K()X6G2to}{<(_*VOK=|IHX~nhTO0w zM&G{&d79a~3+=D=cc+VbgJ~T4wy&%-V6v6W?XA*!6$k6|^4}e_)Q5zSmU^{fTrmOC zgC$agC(w+gPTG*RBB1XI5nbmkbR+EZv37`iQc%3SowiXXv17HwLP-xcw=$@y$c4CP zOA_vO2k+OFL4$iOAr4sBF>l}GWKqG*HxA$eeJ%Rfm(cM_dD#TOXEj@+#6->g!8*6> zUj+>xhp^P`P2l2I%7Auf!XtJv{lAbG7alN@)>!KuAz_+KBtb?yO&7Sf<$FzJUX{f~ zx;#FHP{euumu)|=@ES;Ma6h}S=x>w(vk?dVzCRG(+rqaLVC{hIZDe5O5wzV)RN2K# z5XCl9TLouZUpLbO{Mlo-^+oR8@6US~FB=iV?!@e#jFFW>Z@xGkBQtBqI6JtsYs5^) zueTq2YYxOn*vyPmyE?+PbVQW<@^ zWJg&j#uMpO>i&PCBBjb1fDK}&SWC23sgoQ1f5f>;ox&(T#arV4D}G8>sW@lFpC#%R z?{iZu(X`5s{!Dp4EU+mkYBkZxAJ`0-O`T)&a3Ody%=AnOT4%5MqL(hB#Ts=xtJ^r8 zx3rln;|X1LSt+?kg3O_fxb$%NhbtyiEw>okJ#*0OVEY?FhZb|k2A~rpwk}oj7sc9{ zg%bU|>-hW(k$e{Pff1sS6+1nu$gSQpfv}y4WCBIGNBZ^zF|vih^=QMB9`!c5 zUM9VMGuxz=UpzFoyl`3xy1&=|j*%`8^HqAK&SkEOwi-Cpt6te=;+u@y*;+O!Yc%eQ zHZ9}ZWU(1L>O2l<^YmSVxZL_p$^|ywteu>R)yM@9pbLIhf&zOzTq}Be#22Y;O$l2E z7j?(a_^_wWj5xxxBmBH(0JISUK|ppsOs2L!_K7M&zI}cZH6 zJPEQ;zZN*TF#XqKqe)HO2n)*SXcxDH*yhHl5QWrROVq28uz|nqX3i^AC2Yl*?Uf_d z0kp6$07mfz{(ryp5X>wb z|24V5S-JjKu`X!qxU6#G`W$H-qnU@7movt|t(eYPwb%Py@D~uqn0yZ_?rPAq{rmCo zeT9y}%A5b2$vBaI!6)fq*tKXX!Fdc6duuEe4(R5~O)<2yhLM(b)H z55E*ax&*q950psDD0JzCaG&~cCGrkJ93y7?#wwYW=atwn1WyHwHe!Vwg2h8NVHA<> zi$p@Q0!e(2;dt?grwQm!jTlyqirPGg%=62uq}EdHQeJ~}88zDL&nO49Ou_(bp7o`$ zBAbm?a`U?M>XxG)`Y`k*Bx_s4G3^JBH-kuj0i1?q-G+>>abCgZIKt4o;pHEdCf2|hZlc@u0#hx@GR+6-1 zAL*J4Z=?rV+^-VB^l^bOaU1Ea>eYotMRn<0WEc`DVIE#Pg0-y~edJMU;tY+|6DWe( z#iD)pPSw>tb5{KYuH$T)q8;y@*=Ss%cMU66IlCq3sB-3wshgh-M%GhKJN8HAT8nkp zApEg9ilC$p)3tk~gC#2>CWpnn!iU$0EDQ9{G}OBqYE;Ot^T9b9G_#UmK`qsP^L<(S z!5+t9H;emfc&}izm^O-~$@}o_#GYE}y!5>UMJN zCyrzGW*f*b`o?p&wZ?tbjBe+=qse-=J0*<-@(?5!cqBsFuv7~V5_Ln15*a#A#BOlb zBw?m#TcwAn`RWK}`-_dTnkllbE=E(LgXoPIOgeO-Y?q?^Gjj>k64|_=!?Vi`AiIxI z^`Q?)lzq!2Z|#v2rMTvqXIs;LBkiGGh3sqM{(U1hHv)_%JBmj_a-Cxz0d?~XXe$H1 zp9tlgYJLv}4}B?7+t#cmGJE6CnClANF{lK$p%H8}vhB1e$&yS z%o~Fv4-}&C;|fPwsg#W5c3grwAi2fst9+l}lEwVe+j{fb(8^BDxrVdBd~GHAyIo?m zCCf35Z1VT$LwBUT3&&|Eb+YF-87u!1p^~r#qX=1HT>L|4^P(}23tsU98f#5?qd2Eo zHnNNd4-SmFw@6`d7b=UKulL@B(_lchZNH(_a|n3n{VzN@zAvT5eA=}iAlR^?Kle>0 zf1U4Xv-Sg?H>U;0p zn%mP>HA0@}gJ)f+v@|>6TOwt4Q7_-0%>#9*a!VTBM~;^QZPXCPE~)nSBu)JC40Mp> zmpBS+?k%Y1N)$fxJ>#}}8FznH7K&azsJqjToKTyoKLzo8s7RW#naH}lMlb6!J7w~b zX{QLTkR&nv(3m1Mp8uI@sH(E{Cz0-m=zx6D!Y2(kAuf%tZa?NSmdL|e!;J#^VTX0h z23W889MpfgFW}|0#R#}Tu6b#c)hR`m)>Kh6-@ZE$Tj?CkWh0%3h($cH?Qevbt%s-{ z8>+(;m|=i&q>PJKV^{5n&*bxAI(;&;u08U19945&Xtk1zn3k%f8QZTG%Ii!b68<Dsw|x=r`q9A{oE)|?7;;QP2at4(^sZqrtH3In zMp8ByhwUq2$xA>XoNx`*d}v~p1YLC)Z7Emve7pp6^(Q$~Y<>pXV=mWEh#!NZb=9c> zBpT}bg#6?=;lZeMWpcUD{-4Wp^S#O}bD^tLI)YFO3vv-CmE=I0xzK|FQ6Iw>3p54= z70b8}8s7a9vU>3hZoho_jT^rcuNfksD;sq=D^YE4M(8Efuu163sW>4-wFeaNZqs46 z-&@I25ZtWoX=BJ;lB=y7g6tdrm<9Bi`Y=HCdv>rroxepi)aF;OnV~$}R;pELc_=r2 zjb4ywK#e!q6;v_E^*$ErkWaD%n|DR0kI*1KB2>{^v67e{oqUtil{|Jkb$W)mMfxa- zRJ_j({}EyJk7*b$e17%|o&%TY_r94a2Lk0k{y8ujePzO?EQX|SgLt^Oq^fvulmr1d z$<$Ft{(e672xvz`p^`r2C09Ebu5;#?hE9c z#N}70<273axgQTixOychf&6@)Qk7Wevi+VeFP@mL6(8@`1fI9hz|L;VHa*i+eIC*# zIZPO%4dxPbqB6lX>@L_bKVVeAn$39Ezhzscv z5U{^*3(FT2H*(2u4D7i>LrhVqv7HE`gQ9cA4yoe+@mti|it_gGOQ(sUFhaB?SQS_f z#)NMyZIcNNBTQ$-<;3HFfnKNGmk4a+;uZHIa5L`x+d|R@_R;-e{V|vyhO(l_Ck%eZ z0H>qL6RD(IYW$6Vpqh`{q5DD0cQXc_x#;GZe0SBmg1aEVR5_s2PM6}%%M66g%d$aG z{*uQCB6q6~y3NX0v(JmmQZ*9i3lGvHTCY#8ypKjqbcv##z2T#QD3T4%Kwa&jgj1R3 z5>Jkn0`s|>UxZ|T(n9X}>W=*0*AOxSZrkdXo8Jxie}=UE*w)ioBU&R>&5dmvvQPJs z97;QHMKrnE`iY4NLWSAIXk>+n2LeNqcySmC)caY=)@gh-RYzP^t(V1a0eQMp6=W!Ri^LsoP~x`S zsu0NW@C%4WEv?cUCc>#uPQb!Zp2;>ayt8n9078nZeY?{FBd}*Nl#3Rw!8{26MEkSX6-5IOu>deM65)u|f38FoK@hIEEkY1bI9X(^BD14I%mYJzpR1z5G#{+Io3; zJv0*bdHdr{$Zf-knsk|0CF0Wyngh;EVTB5be7xcv0SNAqpRilI7`sd#8Y?xj!*jw5 z!n4DFMJ+PVh_{n#q+coeDNKD&-=aL?D|fE$oE`s^xL*7ZYo*vcJKk6Bj{d(vmrQg* z>6rh4|DotX&Sb!(SO#VJM7>=TWbvHeN>@2;~ z@0&reUgwiJnL56GJIKx90e0m}d*2w2%i$5B!1Zs0gq}d4FZu-tehMtfuSgpww;{5d zpyAN=99sCW^ArsSYBH8IB^#==pm6FyelZj|=>H1oluL_;u6IjyPt@NZoRtZzkyT!7 z1odK56%#UFP@CA#CNx3x#AQItEO=yEF%Jr#ra$pyLVag*kz!dqkGDqW&l^NZ^OBxd_xLDVr?>B{<&|D zj_E}5fww1uqtO}|FXRwQ;JVt2_^IA_@ed=5(!z`EjU_wFjpA(kR~Q&F7;$-tY-FXJ zdTSwmIsUZ+5R99!)YWPwJ_5c6QEyfXd$l@2_-M$$u@iG4_U%t0F0q;scpOX)a#x9b zLue>roAQOoGf*oYp387$v3K}yn_yI3Lad`x@;ZPA05&u=Ck8=iyT7MCZuuY+V2)}?;n+isl}ui}A;Qf-OWM%Qg4^=S_&EgQ z`}#iK%#$GKkyP~w1Ljv0AWx;IHuAt7Avnnh0yE3T<5#^LdTHYYioSF<#X4M~DSRx2 zSf${$dY%0Qvs^t|12U#rllM+CJB@`?#BiAg^KjeBagpJs_rz?y(Mj)j!CxhDZ1bq{ zh;4xH;%0n)ScVf6sqS#R_lH?dXU+=rBL#x!=VmG(UJTqy7K2}4%px&F+B#sL!7Ezx zt!T5)cw8F+aQ&8vE)xK7=O*A--w)fFY@)p1K5yF>fqQA2+}QM`(+pU4V~Ok%jM1`{+S|PO2VI+wD3vJu?4GMXXsSEu-MaTI5QLoJW&G=JjOt zK7|?Rko&u5Quc{Mr5LxRvWh-cvdT~qupXQR>+l^)&_jB(z#t0q(3Xk z`C_%J56A=s(Wt9{*lZiZ6z!_v{`?OMtjY2A@k>k>P9TO{T1?O>16EK1&|>QA>`fUP zV$xL%X`bW*EW!Yq;(J%!+{M+|!o=<`N-)BMg$8nSG?9fuhKr<-hC<>tbqzvla;B6H zzC*?*$Z7f%>?cUPCQNFmaHf=JDk$8hT2&}DqLfTkD4Zq&JE))7DKK{L5Hk?UnJeWb z017wdy&7^;Q4`dHdfG?osWn8Kbw#_cz}EfJ%aQgJsovoX-vOE zt@->Fl-6@b@f`&8!C5(R{OTW+9{4%1b%d7F#I>hJU1?u$KTXX*37Q&VyOo#Qma%sU zGH{f)ZD-o{A{?%xvruz0VMv+vVH}fi3(jB;AxK5`00Xg3P`F{Pdd;9)(-6Uq;Z}On zPz>VE9`l#rpUarxj%To-`b+qTkIg~S#ZH7!m!w0ok`nmig*4*U<}@f6v%yaOsz^US zkmN}!%wn04M5{+4OgUxlO0Y-WCX&Ys{4A%6i>I_G4Er={Dvwo4lBX3SGZshs{2s)n z`(rKz)9hRz9qCUMQeDDh8_C4j+`?~aH1)`;(V@w(8#X^7p*~}ogXXgEE#pGPf&oZ^ z$kvH1)3jkpJrGhDC%m7R@OQOihk18lR>SqAGBLwe0K1W*qna3pfsj8wWDO)kW644a zii%cIslf$%=1*f^_IEqN3~Vdpe4W8Wrq2&fbIbJTM)PN`DUm;zW`wc}xygTNS>2tH zBiC^xLb==Rp;o9S1_44PsA~66nP^D@?~M6^)nTE>V3o0~`M|x1kjZsS9`W&dxEd_j z;%Gj>ngRIJ7$N!TGlRWw2D$vfNQ16`jFNT;ZGT~>aClG+8&YOJR(%+Z)jGSVHemak zW-L@D-Vf+b#M&I{La1Ly&T0Y4IH-%F(mTeV%6fZ}1NwH1L9Wo)2K;tS=(V?S9Vz}9 zy70$-`@xneR8kLA3f-vfz0Dp^`k-Tvb^EGiS` z)Q%zgUP%QrYtUiE-)jul#h*2@}D znv_QcruIT`CfuQ79P0Fu?8q?iC${Gd-%@$2+K*L&ZZkdwRXK|FqMRZPZYROvp+{;& zKA@UiqL^OR_Nok5RB-m2O}N53L5a46+x+Gw#Yi>f1!?@Kt?uS(GRA=@^rUV%a{Q(k zh+cc0S|3!NiD1&<+>BgUMcyldihyX_ZK4nR79;~0n;lG46Qej`3t27zc2klw5*Q(J z23O+4(4H{Lppu-3CnMaAz*iSTwhje#`rc=0%YarjV+V&Fx$!gi1K{&_IMD_DU3cb! zpvN`PL2`T0>`Q`z-Bezjqz0Mu{t46hFVN!3Cspdsi?}Zc=yo&3qHUx~v?ZNvWYn3F zmU|Iim>fPw-Wo=C-ro6DRCELWM7l97?;ZEP)6~%3?wn~vHdGDNT|`Nx&tdDaEi;ib zEhf%=2O(o9*@WTyQbj-5Et2TV6?7~{8Pqk?K(*nCQ`~!4y(NGiT}wvD-{9&ZQ^P6HU`%*0_a_v%-I6+kbheCzpnz#} zrWhS0PLt|9=h%)QA0~9nS)6$lVN11gMuaq#3$Njvb0;7j(u2%6&|1dOz;n;r*xxl5 zB$*2jySb9Y%^ejWhQJ=%S1&19GWv1Dx}f*VCStu@*h z_OI4KLSlg7n|8P(0E+CV68sDX_s8CkJxGhw+DD^9YA`<#WxNTo{g1J@)v6`lyZ5_m zU#YGY2jzzU0Ne~v;2hD{V?bEotpbrSkerxMZV&5a5?m$nK+bYV8@8no+^dkNsL%;^ zHrU_KMgaQ*_c6N4&fZfNTu@)D<|bs&T7kT%Q`Ch5Zz`B^8m8P49z_o=jDSQ3e4@yL zqUBlD7cyqbWu_e*qc1v+9#eOZ1^4SS9i+^Wq6`%zy;yO-aJJx=p)^{)xRT`mvFxNy!p?` zhvY$CMpB>U@yR!N(-&<&B13zT`b!Xsn@!DuaY}-oz_Lxg3^K8a)5eG89olS~W#IjU zaVRk<;i+@CDB**6rr|i22SK;<^k@$%SQ4vWZLP>W>(HzXIUb)RodWu?PARZ`kVmxu z8RYz62-gGW{doYKFxdFDpgVL2o;qj@hrI2D4E!vEQYdU-Tie zBM3Q~<-}+a)G(QSVMUx9F)97JC5>e7Ye8LU39E`%+SnO<4*6ad=bt~} z-W^?uI|&smGHF<~bf{1W7OdObDm0A#YR|h7lCG&$aNvYXw;9cLg{>QG&+_WTKr)C9 zUa{Z0bv!<(=_!+{<6BG=gd!|X?<8B)wW+W)>=sy>(y4(QjN11TYQevED9(3Uw+4~k z*>9(46+eYaSH1c!ckyK_8b*b%y5C8G28vP0Dh56Tz?SYQ zR;ljp;*K?|uW!G+0OPP7W?{y@&)3!yZwF{HoYRQ{=B=+ydC4|aD5!#r?k<>0f4PW2gZckiv(da07 zeUBbs_DDAO=nmeo@0+3y2-c9pBqfrCF|xukB$Sk&!R_CYj(v}F;CugUt_ni`*{Xye z(Yx(Q96N0Lpke~3b1YnnFnjRrUwNB4zHy(DcjDIs{8@rgG~=?MQx^8M(1? zK-CJHtuZzh5;rv2L0=E#9c=3F8S*5)adzrCVnQ#=#gJiMwj8*Av+w}6o}yLx`@HQ9 zdFi8FJ@>$iiQF9zLB?hJWknVJE+E5~RSd1mxbYG^HbVJUf7?h(NdsDK3s@}RX^-q1 z8qVI_B?uOK0XCRgIRuI*3(u_ed=Y1r;^7hUdRaRADkNe0GDH0x*(<^J(OrmiW~RDm zPDI+(OQ_QJ(TS4?x{{Ua`)${(>dW5wG$IBPOcU-nk3wX5OzF7o2Kv9vbY&VU@6yk)@jj^u?zT9e zxd!OzjWPvrL~K(z1k6$MHeon^#~H;GZGus0g1E-a*+l4Wuo$9fuI6(Hz_P6&sKNO1 zJ*gj4xaOx<5e#Tp{)Dg-!{62xOzkLt((9_NX$PaP)oavib#9{Hh~Z(t=YyDa5)_K) zQ7P1g;juM37J+VXf2~p(WPJ{Uf%dF;*}sL%;qBx$MSbBr(-o9?GV3IejJmRK=JSAU zBwUJzw)0&mO!}2D14^)GZ*3<_xOKPX#_{mijzUnF6(mSfoM~286ax$P^dw(`f*nMT zMb?EZkGnwQY0e;NPBAwkLBM>?M#El7`>Y=6agWhrdZlxPAU-fPk7kxP`%M-{9Y>WL z<2S{|UY+H=8HF4TKOy$L%2gJs#jpNPLxqU@SRh`kzI=Cr53@q6y;SgQBPWp!Z~osR zepQcL{#gRy?yyi`WlT2fKA@#8yNWLi;wxQZBW(KWW(u!_aoi~SerwQAS08>zl)xic z5oeU=7nY31pXnoO>o1J!;PJGJ)cUTy#L*)X^-an`_Dyz+pA53Ij{@Cg#z0t{_-ifO z+3zp>{&{}!P(WEpOgPhL#`H^c8|TIG(~r4I`hZbT8`WMmQX=N{O!KR_{?nOQCgb&b zy_PNqj~&YKhb(?4uQU}US5X;v%y{ZtoG|B}8u{6^Xs)2yr$!lTlS4wp8U?zJ$$oLAu4}$!h1Mi;_c);AmsC}& zdQ~_mCCHWDWb;k}(NkW$rn^G5^E0DJLQK1+wm4U^iu3+Bgu(+32T{eSl2LMDnd?|c znf}*NcUd|j`Qb+D0{svgqWv+Y{fOkq_8=Ph{ln0Ob84dfh{kKlQlA>}hdkBJSVk*2 zW7FVk$$X#9(r4#|(d2WV;j7lyz z?GbJL15$L=Yw86q{R~yewk?VB=rooWm9dZLM&Fgh-@Zh=JPZ4(TdaWF8DVm=XO z@NUlRuFK0v(*Aac@jk;_#iUlvpC>a+V182ECNEEv4N*K8#wDm#taTR7?~-8&7AU&+ zfxoN(NL_E{*M3%bIGE|lcSJeZxDTns_Jc9~>gU!3_QSmG#K%$W;h{VGcT&62fRRAi0E@)@IE9zz_=8cz`d zvqgQJ{B~|k#Q03 zPVL{DeU->FB`VX;eNVC-=3scgSqb{G$W^u1BUf^0defC+EDH&U1^K{kb8p ziMaC2Tg;vBb+a(1ia5(+;uQWTZ|?>dsVKvRc$8L|ibQdzImakl)Si$<5GN zs7O2L@!{b^lD9%=YR8tHl{|_()ojmfFQ(a_6^i@ISL@~cZzLj=^h~g0z3vX@q+Nbb zCu_>;#jF*Z>m7a*ezLB)3o&H#)e@a#Ob>ozPxFJlm<*;sfKsJkjj-qEWPSXVEB*S32PW)C>~$34Z}Olnk%0)E<~DI&r=u-MFMjnV~*!- zy3JZhnIU5oXRN!;zSc?{)^HnqMegXVZ{5-E2A5txfOoX6^Nabmo%p=cv6zOa#vx;d z_?@aHw$7K}F~7g-orAPcdD;~WU<9=XP?PjK{s~ zPxn;-ma{3&L0&YNWq2SxU26;(3bt`k?me+n`*p{V+|=!yfrN0k@*#13ou2#VrpU53 z-=1R7==qZQ58sA;g;uLtJ<>DP*BG<>Uf;sGMzFqOX5iw&?!0wJ+6b)0F`SKtvH_y{ z`s84RCB?=&4ccqNVUdVDRxFgYH_ff4s)t9C5Ne|RW8#GRHka-3Z+$Tk1=~E#2*UQj zTEyoo8q3jCAo)|aYl)yP@PJ$p7Sc(8j1H_bkb;jD+KHDf{$%eaCVR8vEm4%abGoqDq1^KBNXMN6wH$S1vUNUShLzY3y3yM zm(w7L6iadgYbOYsg?M}ToEt!a1p!3t0YN0S5ubMr4_-P;PW>o!Y#T#fweu3U=MJc& z%ew25%sZUh4KbFR5YJKHj+2GFb=6wG+pWO~Vp{ac6z-=d?8F!jc70K7eol{Pu_q); zraK`s`fj_rw()>xarF=R5x2EBPuSXh001iwYsbp+zTSa{!2qYFE=Fx5L(iHE&#o7;OhH?4xQ1)Xywyk=rF|;m8o} zYrxJ*d1?fp9BQ0dP_sarqe89XH<)A9B9m}dM97yfc1)QOe2t{3cyNdLN}ILmmu#}!2M%{-2Hwn z^U)ZE7zk{Xa+L3qL^u=bEarD*PNo-5QQQX+BsLuY+c7PoxXe8k6a~LCKaKHQKz(ho zXnIPc-{+jB2g$l|D1~Gwg&eoY<_J-L0w=tH`C0`&$Wn_mXA)TcF-|rW<76#J1%N^_ z;IEQ)xM)C{6GZnsFNE=DVu)@aD#Z4(T?(cVv^>ZYRe3qYfkyo> z1H=)7Ss9dpMUon9>u9QhsFqHCFvRD6!T{(1bGx41?YVV790)eMAbM8~N}1g9({KVA z4gpXgKG0GcU1kwiFi(L3;@#XIwFoqFU|L7hNO!j1GckL;YRNl+$NFw-Me9EI*rtA=rPCgkAksY@YLba1^zE)%vZZ&+itH z%}hyX-m0S@&3$>r2Eqv$*s1$uojJnt1q{1`05|en&;HVm)E)kY%>;+H-j4S1uqR|wqRKUBa z;}&K;)VuR>0C9qT38toq-@@I1)WSBlB~qfg!T4yuP-}T9(+@3laBNh|(aU;7w~$C4 zbAFP$9)QEa)2f^RRPmvr5+0e34*cX&em%_roq4(-UaX)F6&?6OI4F!HxDUcX;^67L zZ~Wl;;4O94#!74C&sgHrct@VOx}?Fz`i!w-L>srC_Z z?DxqND@likkK7O^OGmNOm{64M*-J{;+eygF@3H2?&7XqIPZxNgDKufyQIC?nT;HpK z70Mk#-$D#&LZ-(;w zL%F+8a74cQ7?L1T)t?xWq$LMC%8jg*+AB$kQ2Y@l1c|<@ z_U)flQw=<{cTaL)N`nP7C5YVsz^ZQJWkC*P=Y3z@)FRgdl5>y)-??fI4zBN99zJq5 zay0;}ti7efUnRDG7bVE`1i9HbIeEl6*rlX+r9J|s-UpqM?3`TU99*10DM{{+KwJFpWkA5TILG#!X!S+<0GLMQa9(q+>#>+ojsW7mz~)Zdq5?Q|$U9s|V; zE)GSr(+3>{On9|8QCuBZLYM~N17_?t#XNmR``ZcQ;Ap$0N zr%Drlnu;khoIC+_UBbZ+BGH$3MV2FjysLY)dyY_(>1$|DYIUycN_+^R+ib)E`HslZ zeTck>#oL^j0nJ-{yl8ma6#9WbvYk=^{Bp~99C5X~OkxgWeZV*X}Eq`YZ;N-3d82MpGi$3d- z5f5~|&CKxik|cMw2>(o1m4w*==~5BcyEn|w@F%Yn>;4dE!kge(^H4>cZe% zaR}b1rslHh#Gy^7-a?%}(IeMaZq6cq$(q-HkjrexyMruzgzhfNQWWBOq%3W@XICov zMD{!XlX7X6noyzF@x2vxhK!KQqf4ph)tHmrcw9NH7D&1BT^Ra!LjLDf?z7>WvVKp4 zVcV_G@xv@u=~BFqhS%e5Yug)wvii-jqW)NB7N3xd*TLnd z)whaFAXuc$e&H)18*>VK1&4VJ;(s_aL_Z6V+tgg$Fz_ z{qTCmM5q3^ZoMqaDBi}br(m!nY0>JdyHURZY7Yi4U}&2+(?7uxpwvgei!=k~*%ANz zN=i(g^qC2rf4+*@J)-mpl(pzeP0v2P78?pjS_qta(REZ3${J(!(-&75KPx)>OjStdNE;!ht*<)cU{ofQ+ zzL+T&D;LYq+MvZ14xYf~jcb#wKzcGPag)()Y5D3K$UeUE_$s=J!5JB7U?+Ib(e2SUs?Fo;}vC++ZkaZFN<2!y-T z8KiYdxY@1e0e`Ur?GvOd8r#zVEf(Uz)0{qANH&l;9%@5>_IQD>6iUE`rOjS#ZamT* z9{|<&oOqWV#puDs1e1)+M4;I>n;5+wt*%tUu40ihT8)X%J#DI;F#Am;<|dVc%~U&k zwshEe8Dbs38Q5=&&J*JCurt^l6@bxKl&C}&GiEBrhZs*#!gDHnJU+FjKKp*izvoKv zvx6oEQ4zC1iNOUT!w?{__h*a629QJlE&e1thtPntNB(@GE8P8OrhrjEc-qoeb2yhQ9tRw$sU+NPDQLU<{l4dVM9CU zgVIKbFa|OO6jmcA_W`sK%Z<5yfC3t-QE7~YzW7H~BXalQE(6w#1y21ves3VQ8S|V5 zbX23=^+EFfUw%sJ98o9xV4D$Aw%PRq${kTE`%sz@o3^>v1KR$_9)bbIm&jRtwjPM; zFWy$31;3&G%Npb_yWyaCW8^^-Lbg1F&i^k2>Xd1fxU5q1`s0axrzY3cOcPC~^8coO z13DE$NXqcri2tU00BiW%DvTfI>VF!2@_|Sa<=Vjdm-(?JD23Rwi7#mLxt?G(&skjJ_+ZVV#Q1f3Z1r zPv_;29qhb+a&l#hig|G(p0T1@P;F-)#Ql0IJEW9j8iOssWAl8x)l5

p6y^bbpfipLbc86{-UStEnEfCD|7buu69=E9?H~SrKwS zp~&2phPv3AJPI;RMR(_w#>?ymCJ3~8bk2isyy7FG(xmP=W^L?~nW8mutEXJkuBeS% zd8m(~JItF%_Sc~`#pJ5fJfZLKpL9XVF;N3dO_6Zbt-FjAB5D#;xAP#~27fb%H|mI$ zBlQhC7Deosr9TZUXZ4^QPduufH5uq8_T0oVzX~-nv z$a7XLoXwkJgRx=G0yE*kXGz$^_X8ljLDDwQ@Rl^A5ak>|bIqpd| zrtPfDyQidJPCrS(u_8O5$xj~iRfxVf>naN=%4zKWF~FOYs@8FIh$V*I!^cUb&ba{t z*eTdA@?>>MM8a;BS2&bZM;242y>R%oWXwQpO#8!zz)@DpAc*m_aeu4Ho`3pTV)&=n zCH47?%}As}t;-*KV3}xY>&un@C}jrC05^^Kw`IrX3q_CAUQPF~9_Z;$1<%rGUU7t6 zo2(;(jV4U4EtQcIzlPA?jf|%nFjCG-g!^^Ar0EBFdrJj|TMx8llE4WuM@{zaXBhDY z;Q&JCS!c+v*!QrA)_=nd=p`m7HW6Z?+eu?SQoy#ZAToXY4J`Zo0dM9+7}^^Z(E#|V zewI==Is{Q~|1As-7m|#Eah%jxxu2Fl!QxS!zR7aVuEE-(WyJkm`ER z1RtacHJW4igdxU|_?Vah#5Wmq51YMHGsQ~9Df8UZYRud%Z-1v^jWVQq;^RBKW{@(g zsjMb$ATk2nq!E$N$U!qq6^r;$<_H4U*JTWumuZhnIN`Cgw)nVw+R$VKTWFhuHe=Z{ z>8@0So-Mjl-zirb@99T{Bhb{LH|j*?)g)VCAW7+V~eIPkc*>`&3LG+=x=U!N~G+212^aBNlNlB>QDemuxAt zg~)Anv$Z^0Kw@t(+BO1>C2~dVv(L_m$kOZUP^=?dPIALUp??{_Kjaxc82x)qAFKI6cz&^G z)RdD3cTj95c1CtWh~jYi9pc+fDeS;xd29 z#5b}GL0HDemi#kuQy{{qY0H-V`Vsrggz{oW!hbp|%8l$q=#TxK_E*n0{i;N=p>LiX zn=im$pLYe`=HRq7tLsqx0v`1{XW#!W!pBgYxqm>*s$nWLtK1^cA%;j%SX~^sx2n7^ z^}Vk!gWjk)OGl`>d5n#J4X%Iad(x?iplD;ABZC{P;NPSDG$2m74(VpoHK1>u!mfb@ z1i*ha%Htys{N6iOfMGapPNqw8k8Q&FPPzh7a?7OU0K0dIuS6_;CyX(Gh@Z>QJZQRW ze}D7M%LmE37LSb1j9G*rSZCR)E?;(B+zm`y#Y*G#{L=gJ7R8)iRj^bA@S?0CjwD4A z2LVIQ&qZ+ITi!PVw2s>Mqk39aDrLWe2XZkC_A5Jt2c+>pHv=ep;P$}@-)&-`YX2ek zX=hknzwitpyZg4F6;;14lU%N|%@Xi&B!9Y{0JSJ@n2dkYAl373OOBI^*GqFAEJ0-S z*)?Ct*vk0n9AjU5`B;qw?j!xBJ}HY2lr}J4FrIxXYO^ZfhW#yfy${wBGkLea6qQie zh-X^)l>DK%=|^A3B%c}GX>I6veNQX{bod62TgNUcseU~X;rFhY&?t`qm3 zTVNEkEU<8oRg&JWj9MN!nc9in1~cJLMvunRnMxP|GZ>|ZR0+0Wxz}#=Q?uiHKC?fX z$@=B6F)cMRrb|+v#Wtr8>WuMBlz%24elK2iNfH=3x^D3EoVF=C0~P~! zsvcTD`<+WPo05F7U>2h02AB0XzX_`;(%}*<7>5lP{8-N7UxWsaBa$)4K!5Gqywqk( z0DsF&I@Xn#i!g@#WmFqw|F;}f{?{JY8C+E*L6u+1mbMCa?tAddKeBS;e_=a1MHZbW zOiggp4gnqOVR%1!Hw2+l3hkhMrr#B?FM&I|X@R|If}M{4wKA7^=kGAjSoijbLC++E z^GmUOUsN+o+o(ok-3KgwxqnZkXTg+Wnxm6py-x0oTNo;ZwZMEu0KjX>tDk2G2ecZr~3-<@ayL+%M+2&q_@ zp3}kcWI*i4D@xnlLD*JhHjf>bd}L*q2qmE=C2*iF3n3EgiJO-A3B5UV zH&mY_vo`>RiGOS!(eScl(sy*yx9XAKQN*psV8}Z@p9N`9jYsK8rF_@p5UJZn)ubWT z(EVxQ5Oi{q({Wllpwsg^#~z=$W`s%GlGea#OV>Eqg$$SR8luU(=uD&cWC4WYqvg*UN{m(ch?;fU~EB1g9 zSpJNBOI$q{=(~04F`Jdk7b{JvwJGFpw=1P~iv*z0Gkp$UkP|q`ti^tqWFlB-!=kO^ z$~iE#wJy+iGi@bs7;q6EhFBaZ%8|}l!d_(4RL4&<5^u-=jUQF1Hp-1DX$L?#YZ=^Wqsth=nv4;XE-G)IbMGmv+{?RD???{|XZeBK^62DLaTSXyJj*WB?Wr@)E)RS;LJmqoJSX|ft@w@QVQK^7|9=h zuA+oA_(U^MQ29V2IqZhyUgLp-$i5ndZGXz&!XjV-ZWbvuy7ZLZd|e;-p6i#?O9om# z^QxOI`DMgyZxw6w;b=Wnb9$LI34i)cpJLB@E(pqmAO%-NPre(E zX?BK>KLIqOor<@s1PRMkJI#P6gf=bdnKqi2>d$ys?2k{v1Aqs4?0#1Z^hK;pLw|bC zQ4R83#jK_oB%k%0NDmoUYsgKOTGAV`$U@zNsWTrouPqju3(jYdl8MXZ+YcZD_*Mqe z0aT4&%3%LHTN(P&P9aAYzjxKk)ALqr5o!CgD~v;Q1hhM`9E4#*8i?>^rkE4iw)31T zycY8@s@3gC0&V6&YfmJcWs3dDKYyI}xjun^`MD~^sOP~3ol7vj`yNvO&7T(F!rmz^ zTgK?AZFKHtT4UCI+MIa_E{qm*GPdq}N?tI0Oht4;ri!|I;=pQVv8X|X`97>(`Iydv zjh`dy?AN^QBYCVylzHw}Ih*j^kv1CMyEIIu?d#kbdxlQh9`O95xSGgxUVp8m41L0; z*+s8H*(b#YJFPzS8%2b(%L*Q&ps3>V;97t(Y%#EprFZU}EO;9yYlffPUbW08Pg@vG z{rone)_o$qywGhXia_hE!{pKXiv34kE*qj+4F(E4$6`~KW&dYhR2!cL-^lDXvk*al zk#s7t1ok58!Fp)fxDEb?`fvRMm9`S_OljO1pKmd*CB^=Dh<6a;jvlK-eXg`-dNNy@ zso5;E2Ej6-u?n?}UyPb67c-YGFp+JhsdYPD$){R}M3fDwl+?{+zw4VC9b;%>b8NSv zvMyul`$TG4%Ldqzy-ypr)r?jD2eLaox09h669X|bGnY8k0wV)7I5C&7+yNB>IWsbs z(3$}$f4Nh1rERw+oTOsgSg~!hf{IbGlNH;xZQHhO+jc4yJE{1u_xpPH?y>*wlkR=6 z#(1W#iEG~TWRVjqDANlY+ZqDJZEc+BnHiXP0CMKmhR%*kw$^gC+%oh^KvQSHUp+f4 zIk~6<(7?&u)<(?03CIIb0~!OwfJOio763Che>XQQIY89b&fUS>)XWJ$^;1cWnwFOC zKQ;fj01Vy#!}2%M(cIJqK=Jp(1!!e!XAQJ*`U~-Y9jFWh0-Vf%026a7AV5@JK|@MT z0zf4p_Y)uiv;jI8SOFBA4Xw=VD1Pobuh4T`a1(BTY$NZk(IOYKLz~N zo7n!VAUg-!zaG|qZGXWOY#p5(jU3GFoB)5bDu{{yyG|!F1E+s-JDUGB18hzHdK%jr zIsenrzifYD{#u<3%xxS2PCz%Oe{vZDe*wnkj&@cC?tgRt1+#N7|5q8#j^;L||5*VY zzyWA#;9zV8baea+^B4P{>HKG(fd8d?13Nn__kTs({>$rs)?n`B2(&U`fMsU+o72eY zZ*Eg_8(7AFc16m@#1_EJ^l!bfv)zB#T!0S$8W7b#J45}q2m@nV8!LB!G0+5-e^JiX z>2FE^)&CvK4F7#3|2I(l-$L+z3%&nu)msht?{fbSU{X#7f5#$hWBQjGCI+T| zE6p9n&E0^;3g%8mW&jfdtG_e*f0zEJjWN){%G?I{m)n1h6+q9-#PnZmDrV+JmNx&8 z!2WL&(8l<`cJP<3f7Q<@uc0X-Ek^slIk5k7RQS6HPAcwpe{1_6-N@P+|4-o`7!eU$ zH-INSGY1!do`s9~@B8~(5H|~(_x~p4zkrzkQU}OAu+y1BGAG49OgTr5v|8)TVcKsjnzxEyobORc}uCLe{@djC> zWu`mTVdaiYiD?b=F@GBgwkvH^DJt-*vF-Iu3)|za)PJuHW@wt>`D}MzKC}Bc`ayF% z)`w|D*_#5q%E$L6rS304f7zz!*#+0+U{XEapHfuPEqR9| znCWD7fWCgF_9JyE@IxnivP1MSN^OY6=t6D+L9Hu1JEute{rp5ZG(I{q+=2de&ZEM`$EOh zx}8qmgwXswAk`{qe}nbe=L+;A{N~^2qnUrXMm*T_F$oE2ScK4=M?FEkDwVUv2p;g^ zf~9OXVTx2tTU0HKtV2KvrZvZOqtv=eUmcROzT$+UNN!s<5%EMx<&xif-6!j|_G)$a zq^?lVN2FLfB!&SGOQhLYNFGM{H?uL ziI>$Ol9JgQ!EunpOOOe8x@N;Xpl}iVnV&L&5aJeLiMSXuT!;E&9Q09-(Ui&R^hb?4 zOap+oQ!^4<%cS8?e#Cccuvo*jeP5aP=`ASHH!xLSu%t@Yt-N--ND6YhLl`d?m(1n3 zyxeLG(!*}Tf8~!L=e}moWKb-P`C@Im#&o-_Sr^Ex&6GH^B16kDqZ$IW6mU>9m1%)) z#pWM)8aRb5LU?Y`vhI14SW7 zFylPA4Il8f+RLW|dHTHS7qO!&HXBw)JsUT3Ot$?fVfVY(O;dq>3tAX~3&kP>WTvnE zrT+ZyHUiZUc%b8QIyt8@!P@tDZO3B2LhlaBbJs#Nm*m>1MG+S>`qFfNXmc@OR?yoF z@^agre;PBBZK?b2z$~tro?h=r4FqnBeX!O^7oAOC`Zt~|KKEs-Y8sJZ%n4zw+ z*e%NPwq>8LOsr=4$;`>YTX3`0@gejY`|2ujf1cS)FbztL*XPKJ!MwS3=G`EZ@eOP| z+yb9&4hMHFl69_*otE7yG0kV)fD^6~=7%=2)XBo26#@)8Tjj z3oF{&e4R4bqi0V?!HMnFXI@)Y;4%uPv~rVwR|1mIayABS{iCU&_s=m~!DjvU#P ze>=d-WUeLQ(+i(G@qHsF`K?6vCcy|) z*v^Q3fBJm%G+j}IxN-_#nQpikl#Bwtzo?lq@=Ld6fnERFXt0VqneX81DnU1UJe*nUR zox59Wps|DDi+;eiw%99o;$k-e@&MMEYAY|7NR*5BdMgIg@D1LacmzgA+|bTXUH&dd(hoy3x%de?GTSb&4W+lEhi4_>R2>uW;mE#rIAe5=f{X`WcqB z7SF$v%L@*gwYN&v|D=RN-Yvg|A#W>djP&vY4i3ymQZS<%B`k?<_aWrAfbHW?_4!X) zA0OljHJ`<04N%xKNhp|CB4hdE)(JLujSL^V=xN?U9!q*-q!?}~a$t%sf3KHQSCr)a zS%$vkZ-Z2Hi!L$Ku);CUfala{%9#CDAwyRR0jzIimcs_GdHOqv3uKo9^}Q-#30=m1 zR&wzn1r089pG!PU#LdOunRWo1{$@*ZI1*DQuLNVy2_6~*rfI_k%_zZxC(K>+Y=%5@M;@> z&~{|L=0}8K{;j)4npfh0@YCDogB)#58YENFV0AWjGPg;T5;#H7bsD*lMUSWKQ1PvW3XXt$Roe(R9wX1(u_~Ue{Vy-u@LI$GDa02 z%z5Idxj*Htlrp2(;!+d^y&NX3&=d`kN-}f{#B%52>8SDZH5B6gQ#C-l@g58)(ElO;nT%f z?bQtOT|-5b$s`Kb({(G=u%osK2Vn}g#uS@D`Yt-t*uk;sD0fCW@MypwWv)L9IX^b>S_bJp|D=#dAT^;Ws8<>=1 z^?N-*g>*ZYO>(+#!Bf-4n75;}z8}dKI?di=Hdm1>HY^JUQYB|$b&1JqA5D#XS z1r>|nf7(sxQ^4ud$b?Z_KzYv(kyall&n%F$!gvXo!FOCtHy@)6I^Xp|gq+w{0?jyt z@!91;oC`KJ_*V6f!$OgDjzSoW&1Fm&l8QTFr#|#Rn|cSb694|yiIYzRNXl-_n}Cqv z915X{-5l0U6Am2jWKAd*^ze)m166cmr8%P_fBlc)GWwgd&y2MQvN%2O)-Au(zV*5n z=8QAgT92BgGVR3Fr0>7ykITCkn`NC?VDa2NX1F-5>l&U^jak~t;fvngMA{)q^#wf& zjtg$6{nY~KMef;a1gU;2VFkAr=?=HO&)jW9X_-`c0G+FXfL1P8 z?g^+_AYm~>-@uRrCgqzR{kQHv4wh5WOIBGqw(Pc%v=+_9F(WD5nq z@0tWHZgJpkgf->mG3frxzph(TY&yd3vOpwecF2o#PO1M$thhzFbM=GVP_fG23|rnz z`*8}4B4Dn5x>&@9$8pCG&fA_>@!j+TcQ4sJQ~e@D$>bv#4C}jhD3U-;7ImyNf0+`2 zqZ@-w7WIxKAL$E##l3!`Gea8uT898^}g_`*x)4Q1i(v zwx%w`e&4IPE~ZhUmv5(NMTzG?!wB6?hUbP^6XvG+`RI^SRmNLwB=co9YZAe#NzAE>bvu6Y|E#x-Oj5N}|2%r3w5P-q#v2kESrthp;R z$JvhnJ505QguINQCayH$O%B0i0{(|_F{B)R7GqCP^NLy&&7-)gt2zoBDy?H^S zKZ(YPZQ1^wB?5@vM!R@mT^f(WgRPZ`Dm7C>*=fqopnDa8$(vKJ2#QN#HU`pm^Zijj z=5~g?Ye1-rtk$oxfA>qU*YE^F5xR@7;e)OHKI`Y%)lrhFf)jZh0o%7UNZ&p*u~x6V zfJYDRuq;Im88r4MNsBKD@5YxkJtfp!S=Iav4wx7U#|a}Q@xmRKQkjNNf(doJ7Dbzm zD9Wf>U6j7?mveooaFS0-kj{ zPrqlN4}l9Vf6A5eyfQ$~41Ei^kqk`_HP3BB<-bgYDRZs^B=Nq!4qHzi6(FOMCS`)U z&wBrARsed%_cCK%d6^st$Un(kRrlnDRZH!3Ts~r~BcLENQj+9pGy^8PD6gHYss*rr})jM9KKzVF)2sMWibdx?X?G z)J8nb+_1H#8J<;CfOLaBnt1f*@qvcTl95I?kf;@g@^bWK zMEu-Ce*r%HUK~4TC%#mx2>c-**6z!=>dDK;T_fESl0jBvFXqy?m~#E(9?$_Bn=vT; z+#r#R4^M^*dN1)D)Ek7JylR`ny0+-IkBeEnOO~Y8&ZN}8UEfT=AKT~f3)H1?-4aWX!W9~5I6ZG$jMWSfud4s zKB;aeLkDIA7G+F`dq762y@|D!@yH#^Pf#mHE)@Q&X;VT%lW2fy4}*wI8cbIkT^K)% zP0~hEK&DB^RLL#2JdtDFue9XXZS6&O=-miL7!r@=00vp*DwIuS$r)Y^Qo7z%@Cz3e zf1iG7{_bv{av3|5VtwQsGxhGTCWjMl^?7vD>dTqcfb3lxH}|be4sKim6uvfh^Ez=I z<917B{b#50;1pDcnvYhw0{-B!TJ?y%rzU|RhlDXdVlUV^{?Pp?l5T&jE678mq_S6C zhl#oXt-;#JGY8d^Kb0r%j~-ly(N8T1e{TG$ahf`=NpUjp?YcB&?C1)HdnEN5uMQHm z!s>A-9&{P$rjqgXY%U1b7=F^#ZA&%6KhTlGY`&tEg6c$)LpDv2-wC}K9|dtB5iLb` z>(+Xs*X2GGA+7*5aNFzZSXL(1bkiOAg>_}qc}+?}Sy4}TInX*8@y4xZeb&`~f84HP z9}g|NjnOMY_E-6dQJgEm8J52szQKuA7Sg7|#XAJ#ujDd8)a4_;z=)jLW;Lvzs}(VU z3`M@v+%-E4{^9ayz>j;K-uHH8SP$@P5;8C)ELx9=BVuhU>qSZ}T=RyP^gbP-hT@h!(Zt7!k-pQ*HN%iFK zN#*x>CmG-FmCB_dRez%Lh)Ng#!2ETZw&lXB*-;V}6f_`;#MpjUR}+->&$mGaP@u&mn(lk4HP>tPu+fg;Wl3S6(0#mw| z*SC4A<}-vj*_*D}(E``Ji)74wP`2`~#KvC~Ub;JST0xOJt(KumWI5j>_35y*f7|Qu^~R8Gs0;UiWkmdJ79p*}0W#8NFf8Yrhyjch#i^>4D zY$?(maZ`GE7TVaHv~Ib~z%AMGISGjxRRmw2chq)0{?G<{3CW)+dAJ=@4P-V+h?lgX zHOxtUXz7PMCj8ZJFK>l6*)4uK7LoNTEI3F6399g8XV{5c%HIk(ZhgThLN+T4l{%$0W`{Xp_gst8&)7P>1M(i~wm>TY1?ks8N9qM7eaMH=|X=|LM^-gm$W1 z*0RlGg?g5Xf4O4!DJE{17B~Nc=-FyhuKnPPS#BLhShACK)8*)?bGhZhrJ|qDM4zkP z9U;qRmXWn(>Ea0H26Z{YIlt&yR~;r~)8KMCb=>1OQ32fQd!3yCTR^10GBZK9t)L^6 z_cpiGtMwpdHDjM@S!?f}L$T!N1Q@7yamwV`<6vQMp z#*oeEu`xSfa(|oboGVl-weK9F9N@JOBoiWJzFhyXi~k*z6~nnEaG$cJpcfk?D0dGr z45935an~1CQK6~(4nZFEl+f%xS;p|`y?DM)P8#IW>@yy0L19Cx{C}mOBWZ-kf>W^4cTr;OCHh+*h8+-HY=N`GSpxYc7jzOx% z<}~mUcBml4%HZBHFpgFZ6WH*PguW=*v_y1XOG794?Mqklnt!{46C^6XNYRNFHw_^nd$ZC7bL`j~Oz*md+8)?t!J*sk|g(ovq^9(L3r zm-M#^?j=aUB<(A43WW%fNm9~~!&nSejB1(+N^qMYbr?R=N(-tqr2%qRVeU|hIbr<> zI?F7zC4>s--IKsKlDd1xVdXnj46O!6Je_a>F>9ria!p>#b*J&yU6WqR?pK9F-5E+@f zwSNYQ{z-VcN4LFHfJ-&0+F1lQQSqWPgsEW63dUxHeRB2GS@Q5^)2{lGq;|J({sana zsXr3>3A%mRw=lI|KIQX^iiV8kckF}aFrW-WlU7Fh?V1ob1a_d{Zb2Jwa?Kb7SEWaC z(9G(YAuZS@T27u;kc&=$$GPXhz1Xy)(SJoGV8g93Y{A3&0{M`j89LB#QQd|(>*s|W zS@-*@X9ALLA*P{x2Mf|8jSJJNp;^*fsZ`=!SCbOW)ug+y0aKEMoU8KpTp5eXItYd;D{B|u zk@64Q@H`L9QdaE={I^@7ZAXE?nJh!S>>?-z#1!_nY*Axo(O5 zBSO$P3|uo$ArVj(h6cb+Q${Z+v55D131;v0Ae(!&J1rU7q3z}6x7kyT)OEQfg|X}W6o2ILHmO;O zXXhK@1skwNn+P0G>o==Ji?9rO!WEYB*Aj{+Ms~ymD50=EP43!_Uiqk6Mu7Ka7fqe@aGY~ z#)yZ#Q*uew?jsoVz_`zpl4!g(Tt0&cf_xYEFe`oQivKZ+daV?S`RX$<5`d-^+CBz$K!4u?JXnjWqmX|JVx#aXv~SPtQT*E8(6$LKDnq^eYyQW`+yr zt>1+ZwAfK<>C0qovwxdOpgdauQ2DMPT-`3XCjTpRHvybK=f;%wRo0-A-Kw5l=WLx{3^Yw_=h^i z@Fr?vI`v`gcH6OTe{!QX<3Jvy+?6Df1-Yi8s_{wM^P#WE?3i#|qmG^-(&>Wt)@h|Y z38zL!f9U+2b5v+@piu8j0dKLM>C=e z{?DMsfPZ|+gzt%}9oA@iC@zfoVxc9bC- zC%^IK_*8Vnsi@RyoUUMC*BOD0SF9I>$&k>hSsbS4`0S4N(Ho8u;nmK8Ib-g1 zyMNsuK}7>5nPbP2cxZ^_znOq-&f{DS%jCpM1Ur4+87f=FW;v;1noVjcH5E z7~Os-#975zs$wOxoktX!}f!K>i*`mO{ic##!j?+2P`SD`< z@oRK4X%ZPW6geMzZ+iMl?=yq1&fOCk<0QJoWnbE@K-*^ckQk<`gip<$~ zMSdcs>DQxJ`d%n{8iSMuHbl--B!9OdMaB8?S;$i=xoxLLW&fzslE!lI_SLXEtxHZU z{?F0e?5USYr8^EOo1hQf3?Dh8InF?>RBP>y1=wP)Jl_ccu`Ash0nZ<^Og{p&`LP0v zY>)fI50RXIC+aPd=8<3$QE;qMc>=O&zVst{nVcp|FpMTo$ZGQ*@nUGDz<>COft4ks z6@wb)Ccxy@8{~GBvvGA0%^^)KXNwFxdm{I{6(Q5|CGyzElcqOfksU%+f@qislof8a zJfONxZL>MQXNHQ!g;1M&rJas8cW{G#C(Dy0=}R-M)L0 zIz|Qa8-kF_k`OJB7aP7js7L6k7fhDMx0W0E6}?zR+fd})IwI4^Z{qkw=bmfNGc>5H zbD1M!5th!vXOQl3H2_DrKGLI@wV6a!`&ENZrHIO(Q?WUTm49k$VWfoQe4ztnWMM_` zThjwhhp6)?`Y&pyHXcoF(S!l(0w5yd3!(;u5M5W5!zYN>mi1g_rM;G`%ONGP0$Eib z+SJdR!U8i58nC?bKaO@&{>S~nn+*DKEe)psIyFA1FR!L0Im!8_Cy#Nby#wi8lR~ zJ$LO`Wxs!gRFxz`N}=ZVWPcC^NHofJshhZ^XZJqk(+uNd`-`Zs_-T^!eKzpv=1t#d z8@^<-RrortgE`c~n448P-`}1$!s%=qvH}=44%Gxri+?cdIh7P@eOi-U+Le! z+r2RdBUEwKpiXFS_Ru1c-0Z~sX{X$>Qn|SIBh)4rvxjAfb+DeL_PluWNNj2%fldIa zczsJ0Wq-4i;pY-{Ulf*jo;RxHYa&lSiz9}dz`H&>ur?-;YAuvPg6YLJo8(!`UZQ4q?mwJB9Ya|C31|5 zc4#8{G0R$5X%-&6I2d?fY>VMmoVWsuJL9+8sDE?d56%?H4zYBSaWOBDW#~47?c0xU z;01}`l7*N`$nN}reL?S{F!8AV|^IX%jOHo|D}%8 z()LrX2vcJtvdIe6&vz?K0HXk;WM*4B*&iXV3}SE<-`I3bGTkz41T=oI_;6_VDMavw ztbcfD35M9%orc@fn;T9Pve~*0?3Xg9Ql%(1_}0QjRMwry^=Lc)`rtWpg{quDrpKEZqUaSWTnT_7wEc;@cNY4;a(q$J3#LNym_392zG=A;Ph z{U-GdbO%SlHK_lSwDe{Rs|f3G45C@6g?}|baubr)pnMt(arGJsgM7N3%dbGLrux>t zxzF`zCz!JNQp-mH;+YSofih>-VgJIt@F>umb#?{)*Bbp3*0WC~c#M5B9&Zt=Y~+D! znwkYw0pXg-tMfE>wUYK7ULk z`>aFdcCVy1MSAx}?sCuX9}9E4F^dPhfpkCMRfx%g^`w=d2p*L^^p?Axl>5{o znFCq581gyS;cou$$~7;!+lai`DSt0b=U%mmtiw#2c1U0T(Vz>p2%MEXDtJC6S3ma9 z9vK`dy4*JFEH~1)x+D8=dx6=*9KNY`6)FiiHsP|82Z1skYdQ5G639ublX%vywhUSZ z8*~ja2WL(Ewjl$~ar@*u^P1bIPUMowoW-?7g5lCCos^?Yn|_Hu4oiQ8oqx$@T}dzL z>RH^a{qEO^aWl5`;5G-<_T!70__=QiI&=##i=#!5B8P6KIUQ2beQ}e>Sw+!Vccfi2 z)+3SN&LQ6>H1fqUZ`|5L{_+Q<$Ych5U`Eqb?vT2@+m%Dj(YxLiX0armGjZpeTK5^s z_JT%p_qZHxZ}K87r z?7GT^nb6k1qlLQrL9rcd8}m7ST_5zPoYMb{B#IHEI-`EW8H6sAofNY;Y!3FpBBYh4 z>a*Tj96#&DJk`a&EDUn&7b`qrPP9l={EofvVO$v41y|(~LRutf?0;%e9}U?yQPuYA zn$iwtQ~n(ksX<<`Dm1juKp|#EzdKBEXO)4jF?$xsphM5Q{XD*Yf8Ka*anVvw9b(?{PmAL(!-21oxuG-S3hu-S(FC#irSZX~9WJ(7YO> z%%S3Xwz=q9zZW6C8h?hjnvbjdh76ZF}i~dt? z{~~L1*1%ee4$zovaWndD`XV({gGbv@Mb#1xwdVk}8P^+5rNt1RQF5jDHc438GMR;H zLR%B%n>x-ldE1RTJQ+h`zM$+!j0l68`5z$}Mg3xCt)N#Z8-L(t`>{#ZFIk9KZy`?v ztD{$Xpjvn}fhReaT0^fNb3&R*X>f8eKlT|})h*0fGa(0p z^|7RqHF<`g`y8@3AOvXVs66e+FY)4e4S5G@GvlmG z`BKB{YBYd)q=k)w9V?L33%p^a^V6oD?d>~HB&ZT(Tz@vh>Ex!KC=yX*gL*gYp8DDi z93NYMJ@PAJt7j0>^x}oRil*%e8^B|xqKoEL3Mft9B9$z)9x|=>`yr>s^ytMNSVMA` ze#Tzd+pnoePRWzA4#Kh4tOT>?f zWZaTN=5y6+Bp2r#1B+AnjWb6A%e|3nfgcL4G@}s1;p*ZHwTBP_q z`WkUAw1m&YB)FK~c(H-@)#bad{(uYeYv|k(=@%hx%u>YrW!N2YkcRV246G;ye$J&! zJAYVI&^zV$?|%>@M)iz_d9(XD7&zzU)L`!V1M}v_g5$k!2o1TQnKT4G9ra9+5)@%4 zJU+J98nFn{2})8)$}8Qg*@_a?$~?rfYFTh;?#ONOo&_D*p+JR@SW`1|gMPvxw{fNn z$YHWngO}9KSkKP|@f8qZs$$YB{)FH=-+#8Idb1j*_MU7aRr0tvjMH;(jjcT6EM5X? z;TlR>NZtg5t^Octvh@F>>nI*^T*IR+AF8xjFd}}D0Wzk^<26%6+bUdC z^i6}lK&oR|taC#I=0+)?FNM<$i+xaWDykXUIqL(jev>6M*+nhZym{^e$?#5@vCoLS}?F~IdZne zVDP>)0fP%kG*yu%#r%%t1)^JyQ7_d`K7bTDL)`u3IPo@I%$+rV%BAF{?h6rPO5Rbk z%TIgZRI64Ims~mI?Cle8{0B~~SbySGS%panKlI4d*3(O|81J6BE*NN`JQ8jd_bA(G z?TC2w*DWnn?z}f@x&HRY^l>{q<8yR=@E?EP;Q=nl4VBG>!16EdJW zUCC}dOs4n@vqGfUg`+i{s=QHa%{;DZPIvk_vL8;Qb5m}_!DJef5`Rp)MDEi$X%v-K z=|Sj}>6YoQmKBD24=7BMMo2Xda2JqU2Y)eXQ&BjZCly(!s4mPrAF>>A507f0j@M~f zFo-7iSx30$cqtUhH7aB)xyF(U2bOrC2c$SphF}q<>^`IfBGe|L#3yiH~FD2i?WM+FqWHJz45?j>WX+3F|o{%K{(6l{ z!GLq{Uea?VYf^mDISNp|g_-ZpzEs@>;pF1rGCrmsBY+dkn}5(RIQA%vVu2rVyw)h; znosc-^QnZlZ<`q*9bGfwXLKukxu=94M!fsYlu9?@II~|;Qyk01(GY>GVm)A=!TWeR zsE;7nmode7UV1u4ZO?X25uqQ&W@-tv4j{9Owf>Ia)!p&1;RUaI`=_*EVa%0B5$RNC zla#UcAgCe^ zw0EQ{Anfaf=aYCY+>Skcf%1}!R6QJrWXkC{*n@?k$-)6{ zbnBk>#{iT+5iO9DZir5xIRBg=u6n|8eM^O9(hb2^g5;}7BO8X^h!sKda|bldF6D9$ z{!tSe%KC(Tbn*4Smdn_l?t>|F1h;d&W}Rm{xOLyTQ`uHSN>~-mcp0zokMz*6#uhUSShrunt~Bt~JjPb?o;K)zyz2Biqmu-iLG5 z!@R>IB7Za{MVrEKMp!7cSE@nQs@W_U2zotHJ9V%M#(ei$GKW`Mf zT7R~RSLTe z`cpfTn$Xaf$Ot7D<|3p^YNnq|g>?F)>H8&Fa;-lo<+v=}BqtBIaj<_^YecDnU3Ics zxzg?ZOv03GX|B5Yf6cQ?F~Z2$G6B7|=3DrDGw#C^<)QHbND%POpi z@jK%n-^liqRo)iTiO&j)4dc&lAb(0kN8ESNxj0h-)~(E;A^3~ElfZ96E~cV$Y2>1@ zYPR@SuIuZ;o}b!NiO5PSujRYVQd}o~F&$4r+dOxqM6ghe@u{3k(3KGs37?CZ@TA?)^UVMWO~fBGC{N?7 z#}|Dz*-(40eV5~(SO*ToqG?tYQ`e)3?fOQ(=>$3@_$P(V{YwXijl zIR*&Kj=vZbQ+ykdcd2yQO=UHesi@i(i3oKq!Q+a3}?J-tT;u16> z-{DXjhmcH8K|_`~*Mi-Xw625z3(p+k5C=a-+^LY)lhaTk&XMQ1#S!gTAR>3sdyizS zg-*2U$MHcj?LM*8v45Tyo%QrkVMqaj#spx9MKHeL(izF~OpEX~otz$qpzF5fTVFfB ze-|5kc*ARIFUDfUzrC31tiDSBqXjTihqQEp^UAUq^3wEtlSU@ z)D-0d`GN!@LjUN`+k*QZGMLUdob{;NLuL^%e_Hk{0*8;&rUKIWq8;h2)$E3BZyj{y zp{vU3GrFIkXtbXSBQld5FN}xq8iIWSO6hzyVy*XKuG8D}BTeS^IAP?*-r0 z1&A8kTGWhZ`+x2^l3dj_uLsU6xhG;C29q@%%$N)i%Wdk8gjbjs>HS3<1n}-w9l()E3M~Y$065WpYdEAbPkq~m`2BNYB zH^G~cw10uJH`oIuEHRIZl0S!kPL?E#ete>^b<<5COGoSNQpXG0&md=InrUAInTd4x z+@=P*k9<%?SKePdCVHmGPTlDc#|>_Xeb2~}2YtyFJ|0{0aOdcP)6vT)zKxvTPMehU z6q7XeVm>@Y<4IM?qVkDQIr6%#X#08A{mWH)#(!(n1>&W)vm}9DV}_B0eiMIUQAz}G z5zx_@fgyY07oqj~;mVGeUZ~QDcPZ-}B~?yBYm!M#yyL;6L*|qiN)`nPadkMDdwH*! zCI`=zoD)2-Vn@f`E(V?4r~Rf$k2>KUDr)szL&#wSMylwEU19*sgmFG=$HZR+BdNw- zdVeDL6XkbHbEKeppd2XM^L-E|V*8uw1J^A4f-xk|S}Y3x%KRJJJ5fM}(o9ltX^4pv z+4iOZA3!W8n`@5>+QVZz5K;9s;tQIf=*y_9B)r|*!7&aAqUnpzpkOtVin|eAwGnHo zNr%*NqflcuZLx8lTWh|_%^Ln%k3>of+J6y-z75^QHR*nCrWYZ-Yv03cR30_U>0_Gl z=kb@D==I#Cqn;ea1vUB2!=`z32J4NM%DtSrd&mn16QM zQSC_&H*!_dxgOM|K69v4IusFVwc7T)9?K9=%TI!Hz$Rodf;)Q{ z@t8dQC^lQv6`c z8g>t&Q)XAS0rKT}>45Slm7;}l%zwzMtJCXq`-ZK|2e&Smrl*VTE3gK-z85|&31TVI z1|I2C2YGf$uY>(G&2l^X8UWK)-$~aciO_7A|J4sU$7`tlkdoL_gPRfL?rk#2CHj5j zt(={+YkW$x%E^omc0t_M34Vw&$mOKtOvb;wTpI1LSLkNlW})h>aYauTF@FrF5C}gi z(9?fCRXnEbLE5wao051pGdGl4TOVVgtbJ_c8>*=NK$L@rCH`wL&9G8oYlQySDGd$r zPl(?Z0~osyOyMljS0^xw7f*bIS7AXyRoa@`qd3xuaW~!hd2Y!*?cdS0xHs!i$GZ;t zNKCf<3RgS(td2M)Lz%V-E`PDbQwyobpA)YcO3V3aYg^JKw&q<3Lo_=#g7qFw5aHH9 z;D$=}$|+>5{VCsNPfC?tnP`HBHtH2Rv?^#L!+lnrAh{G=7F#WfUvIG2cBSF^sC1hhAUcUr)V>wOqo*rpbH7l0h%$INk*;g%bB%^8%s>1to5cOV`_33csDxgMat39UW*jRGLxu%}ETu zU}o^M^&c+hj}uVbA-_`9JbABvysYOTztgE~E(J*XyOxc;xXc=0?2W@T#Em1g#cEV1 z`jj(ExX>I6h3GHxN1rRt4reC%7JlF?1JK|=eM)J)qcGG(g8Ta({XSc|5%=VSq=oe9BZP$4wA5NT-*5=gC?k3S?6>m&aE);Le+uuW%euEEgMLg=;mOKYOLdHCs!&`5XtjdtW_vUu%|#<}o1O$^uj3Az@~_ zBTyq1dFYBs69>7CEc8wHezBiLZr|)Z$Q`C0S5=UCwio9T!Ue; zTOl+0fEwsN!R|_Uu`UP~J072vzGqADh2B9poBnTXQjklRAI#hN4CE)UKNDWc&XU0} zxq$%4^wxmM>x*>m`Z$AFRaRa7yjVKkkv$S7pMO3NxWg6&G#N-fgBwc=giGxPx}VGE zN}m`2J_tiXd4g*&p;3cpjZtx^R%pS$OvxkF@aPHx&B8y?>NQ&&W?h=v`V}N3R_sAQ z+PG2gNMy1ZT762?v#C!^E*aP3!h!Gh2-IqPKME5O0A~Jg?h08q`*GSuHen|Z}2vun;X#`&l7l?5ZB1Xd*@pvQ-_H%4JZD12z>K(PF%nla+>`ALiu zr-FuKw%-Kn-ECtJJRvi30`m8WqgHDo+J8Nu<(>nbcJZs)=qS|rKojW$N&fb$o&KJj z39!s;ZQ|xM6VMttwP@X8BU9sdZAM1i6wr2IWQ0pgwfngn4$9(k0OA*>eyX&I z^ut(hCXjD4-(n~8$!CDW;bIN7Yxc~zsocC~P@&wz&FtMMBTIp5F;eMrO(|KUet%eT z>2&ah1}O?W_s@eKW3$QWwN`SkNmJC-{;5zvTb0o){vxM+VPMCnR?4Sxf)J%wN%)bIO9K(tg?N|vY(LPvK|*1@cmnJ#+m z^M$pIw?gLbmbvmn9^$8m=JQ$?!>Xxipn5r~aMrW&3`Bz@_DZAD`%opJgjPA~OY|+% zOpLVE7H3AKi!VBb+z~i|UTYE6@mYP-yUsQ>WK2dR70@1QugCiAAD=XK?tg6Fxxq=H z>DV_GW+%M=tw=o(PQP)x%aW!^wiL;;8eJ2hhT>qCdGs|_bg0jCL0L>dfr@Pfjr3`i z=H|Z*8moYJ;>D3M{@gr86buc$ zNDqx3xymR`z_DEUB)QCSPJh#$4%h6~=->^hI`7EExuo4!t?5ue9lHjJj_EM)4?^OQ zFau-WokHv<`X^(MP{CIN2acK(eh}Wk=JI{XF*Qq{x4EEeA5{w@AM6w5>6`AxZ>QPd zG8SM#vko97ZlgxSCJ+IvVd3xRIg%5%qbz64>Xm?85I&cbo(Hi6RDS?*xHd*Q5SW** z2=#dOg>!kst~Sx4uI`V~?@G;~zs z=8-Wf{mSw({7hDS{m-vRmUPqUZI?$!JUh(zPT*k!GwMI}1%K?t^%v0ESb9#R>;|;1 z7Su9G-htcCn)R5M&V?wphXXsYx0R|B19c~Ty8U6L$FBk;!Nb!`j_!IEf_fO3?hAMv z#U+ZD=RK}B$2jlUT-)~|;D<=H{ugr8tv{p>Tn9e1Sa*RJ>cJ(P|Kymr1Z&%8a-lO{ z=|otllk=S6cYhoOg~-)eW&1W3xpt_#HN{|l<;aC9xam!FLYmilOIZ`NiLkRNh+&N- zpzTZJKy9%@&&7azRTfb}TQy}wk+0;v!*f`-g2$<-${<>^VC}@eJLB`^%BkkJa%iZ9 z)olwpxm_N1RUWOoAAnR3AO|OFnZ;E~DsWUvpln&lr+-v3yNHa9fb%~}a1)Afn`QpU zYk3(33f)D@5GxzP7q}dgv+{s2=z37RrxHBKmJ){WufEjVDLNva{WJ!41ERu=IPoy?*#ctM_rtgqB`dh(3bTF*tnX5r)?~q8TvdD zzj-ttynh||X0QR2l>UHd}`Z1wtJ#G*gXryV}0avY2L?jLssuniW8%33k9xSN3?U8AYmgeew-!=Rfl(}x;8l(~_Gsy( z7Aha9uTtCLj{8Vu+IBo)jYdb__IBL#mgHxNv41YzZdc2CKXc9s3t(q&s2@8B`Oi&d4Dd=J^f0MpgS*s-}7RdnsY~j0^NMH~s;$e}WZym>J&XG|=))W*``aC&cvdD}P zq)G2-42Ice8CxnOyr@&B$?##Ph1ah&H-BsQ7C>k`ndN>#fG$zWHGHh{B$w92A_Ono z4$*YakV!o1>(GXG(Yh?Y9Lkq)Y^TN&M|F(y3UC$2|B8y&AbDS_sU_qy=9Frq1b?_O zq&I`(0O1cXm;aa63c-kC5o;KYK1+>Qb;0!{tJ`SF>kJ=bzz-T#mX7=v1NHEm#SpH$ zzjkd6S)ofnr%ZOU*t~xxVXSUBbA*G5X{_OQ;6=F_GphYqOw!RKoDNeqBFQ77sa=|> z1EE@Op@XTs@RiVGZuqQ4o~6_9eSeTJb*<OsUeZO)ZGx?MVy&`ZyIms*h6~z!h3nOiK3~^M0 z7cJsD9mqkmGK;Q7CuYsQCu-p!XC}x73~NdmFrn18V!R zTj(HK80Y{&NvE9fUG~MyZ*PGDTW)1vK>EaAsIf*w4Y^~%7gVFAy{+Un&6(J27W-%i zZFT6QJRdCXUI|9!c3(u1fs+)mBAt(AJf=hgr|b@l zV^T-Jk>AiKkS9aTp2x*-Jriam&Q3#1I(q{%?*WbvgP)-LIg_Co69X|bHJ6ki10w@5 zGc}j6+yNB?HaR&lm(iL5D1W$Pc%^N#CLG&FCt0y=JL%XqR%{y`qmzzpvt!%r*tTs? zKkqwx_8j~B=FiOjvDR^4byl5KbrtSoEplQ-6?$P)dt;!4y`2j^GXoP3K;F{U*wtCt z-d5h8Tb5oKXznWIVq^pOi?PFzlZ!e5ja)44?Zk{+fII*VpeaBMXnz7=VF566b92Ly z14Qi|Je@4fEnEOpYRVeaw6t{pDfveQVC?xH$X`omOLIE_#oq@vppCtQEzr*8FU9}0 zp$ZTPaIpXa%q(qy08s@+Eh%|P0F|V?8bA_g2Xy+Igrcjljim`d*3txM=M1C0)8z@{ez4%fB$d-t4cYslAEoKPmkS`%Ci|buqHEa|XBoJ%3#O@nsAIm|8kJ*cf^K z_5GL3!O8MpVYoV5+L`}n1atr=pt+HgsSVKC`7h01?tgCQKl23qZ`m6;IM{gp%i8{5 zTK_8sOBZLLjTr+RGs|C}CN6({n_Jq!G5*spQg&wc0A{9t%S~M!{sVIZI{oW{sQ&30 z>c2r4ncCagcz*&+fo5=w^7bx&T>_~7@2br3-&f@Sh7$j`6!^cTy#H^-{jW9p--h`A zb)Nq#wS=pUjl7ZV-v;>io&o$_G)8uSzqP=$Pfr?h_NM>q@DG)Uh`k5Eo1U428$i#($@F&^|BfR!3!Cr%kK2C{ zG5_aT&VR_o$cR{U4wIJn8)x8gV-ld((gVNX5m-&h&5V{V%~ku!*aa z)8C5!Ya9H{{6EhB8Ui5D184%bvS@F@8*G)Dk>*l^oij8crqkEM3_cX%P*Sg2m>*DW z-|e3ozRg`>`2IVDq2UkDXRGJJsl&&oWp^_0GVhx&DRpl?>IOwSC+)!x zM*R}Rv@?xp@2h#)EeLH6CiR1z2_K z@PF=z-sou`uB3r>B&qhIwO+F?ECE#QC3iu8bVX8}>sKrqn7por?kz<5NdaNsLf+Fk zeF7zFNMlSwZ?94I`*HES8^)(*=BDa=G2^@LBhk%HoU-gyj_Hsp4zSCFY(5&Hw3iAoG=buG2JBPO76IdmdTi|asimM<)leAO@^7Xzaw)jK zEFzQ;{R~Ii;J>%dgOSWxf#Ma8U_=%9W9c;GV6tt&X?af)yu>bweF*Tt=Hu7kbes4Y zBT31h1@md>tUH1lW9(!h@`J-iW`9?ghLc>TEVq4iGAh&a^xa8OCKKXhAYk!v=(h`l zgr8{Z%z_-!E;JrXbl&$;f<~&AME$WH78~fT?t$^WcUWSO_!i)Kb6kYxDd&#JjR!VQ z^*&avFz`puqSRHVW$0{eS-Ook~Z0Bj7nRCU|H(BYw8dc&duM1}&VXYnzN!8}X!3 zMfZDIi`p%9&Cw(K&_I&)#Yg)rZKc?S6@}UmeEOsmJgNycM8P5ACiiF1T5qoPXzYo4 z10&QWgg+iPaVhquD2CPkwn9nz@SHR1tEKiAn2e>rB$t)=!P%&hA%Bb7cgMBD?|}Ea ztb_jBTwV8ei~Xg>OA&Zmbo=#5(5a_-RU}c(IM2;G!}sVDOp?Ze*QSE0iq zinNdvshj#Z3XsiBnScCUb^$-1fa`+*T804}F zHQe4%HcDT)w2^#P2gb@;=ci!PT-Y17{l%NoqJ}4Ewt4hO+dG&U_aBgpoJF2?=4ZFA zZ4f4E_9Ff6oj-9RPNk3B$cT=m%B4&J>h9q<3;NKGhm>%VCVw)_M>4V&;(LcJhae9_ zPY6;>IPEumpGtfQ!)N4F6HyROjYXd4;m0jqMh9hb*k%+O^mX=ygJwrIE{%P1B9RdR z-eg7<%Hi(5jjq#pr3l?LcI86mZAt`rf~5#t>J?X}jkQdv$ThP_%G=Rz*UB?%BJ^a+ zpl^#3g3NP{`hU|sW!FkD^5S&RN=(K-^Ibm_#7;Y+)#kgFH>_KplDOBYO08 zLGAm5-?=pR4q+F!xP1Y2f*Q~!U@SOp?+~4`HoHU41ZC@M>=d@yF*f0qBcnwB6m+FA0mhI z62>x!%ulmNalu!|Y2)z3b`KZX6;Gr1+0plYE?gYHLk^T+oPCzU&Swq)pnGfTx$pu7^@I;1La~%i4Z)mEHxK$5SBgMI|!G{_nRPKC~;U!s8!{M&> zV}Aq-Slb3B)w9|Y4pj=p9zEfmG==r6RGad8+5c%ygOLE zR_?czSy?B0UX=7`g8taubxbUvBdnn%9J!OCH6;c_;=F;)Q0HYq2nK$3dnD;^a4iU` z340?|(6lNK@^H>zjK5nd&6#3f<87)ps(&b+Sb_{n*G7d=5s-(bZ0U+6?Q>FQ%e8Kt zMDMBCGQBnQx^2Xg_oF|@O~^%?HW%V|hNjQ$qNDvTRTe%ZakjHchaR9h`B2-16(V-VF#f$$AQ3lwYkAJxS z0?kqHhI0$bDVmMe{AGSN$6;FE$WD(1*`%YUc&|j-?n?!tBAL$fgN@qNI?9@RJtEmt zQ0Dx%lK~KN_eH@bw7D1KS+k4w)Q0FA^NP?lGFiU!o**^?*;gpOJ4^6!$C= zJqPqI&zjr)<0@`1WMFa6T60=6VSfyCTz$V35*Kp+-0hP!$N^4EdJ`#2>x*;X{_sHF zHj5czfPZ8JfB%#PiFZ_2H2W}VN%GBM8d+WV`AR|0S^Kn0hnC@`j@;Ma&Gr_+$rGqjML1$y&~_QSKOO+U)xJSe zL2xOsur|ZWMR(X0Y0q(m#OduJo+e6Phb8D!)gdG&1FOw{Vh=YJI$$#b_7>g4M7L!C0y!YkWiW`8iLmb56Kcm^lGq%ORI zkPmM5CGo)#xs8nJD-1?m3dd zab0=R;avH?Nu2@fTZh8G+~}~r;Trm1l@NO zP0P!&4R)_6vMoYPe`Lm9dea_(P4*wir;}x7Z17Pi24L+i{pRoOR|82CM*`uBHplcN zlpW#-%ZWu)C6qm?#RY}ti2I|P41XV93hy7m)MV4)Gn5(G+XqxwkU4*<`P2dpbR$c< z^$U;l2m6K2wXInXdV=J*N3c@bg^W?I-WBn@5|31q5m-%LHU9^kCijks_?iFPLx8u7k91?BxTE@KISyiuIeU0$wKi^t$UCJ`)cB(NtqKGn26Ry%*faTxiUJ+B z#irtZxbcaYW#vPaEeC&&(JE}()Nt&lim*Vjl+||&%wkN00F%bq=^lYM(m8{tBcXU; zVpTRS#`V`+I|dh^Agw6hgu@)~XjAEmH>+NLa~-ow6#3l0YS}SC3md&mzyRz( z{~^XH8>&rMnW;w`Gbb{p2O(|L!t}O&BNUL##*e=R$o4lqRN_RRdo0L}D z{qee9to zxjP5J8sdNW=T^ZVJ(!d^i8P?@2S~g%w>0MqR63Cn(oh{i_BYR>(C&+`zr(vW$$45# z++gF=dEgxrAuv`tesKljdp0SQ(kE2$TbsB@Mx`}krM~BS8Nr_nyU;_*7$IT;HHXj5 zhPpmzr}w^r4v!aeA(-jrD1h0VHj+A*Rqmntt>AxcZ-}TwgmL<^b!&U_JZi?U)G9NL z!3&$CaO*HCd8T~%EhfIB)R%C<3jaZ{lAtbnWPGx?T8;~nQDc%RE#Mk>s(<{Ah+eEf z2zF9QbXNpdVp(`1p7>H9L@4+4B^Ec5Z${bnyRY5|_wB8amY=qm8HN_y=a0RwJE7cn zNn3wYgHSNRW92jQ(E!b+XaU)9D3_L|^6lL^c#r!{^lHjlS=ounP}p{dq<;#QC6U&L^#PoEd!taz(PMlh7C&#ApS zGC{BjZ_b_wH=zCP86P(``>FU_JSIm!BC zJ$ey;<=#WD`|ciPiUi6JWU%(KQ?#P~E6|ZI+jwgS6 zd%y2Q$_#y|?ONT*x=r7tKopGT#Ag}1>jpIbA4g!5Y+!+#rVc!u z-L|^aq`IBihGMKGJSJrB9_DVWt)8>5Wd0e+nCQSHEWa23qynv1-;l1mZ32HUlbz5c zvgjO|62Oo7)aU5yk$a1sw8Ym9pSS9>cu4=UbaPr&(#DX6#dA^Xstqo@tC&lJh%0Bl z(k5OPEw6JwYiJ+oruDM|L$GCCQQbCp!Gbi_^W&j1uks##NKfpBL*p1eE^7G^UYz2y zPak7WFj80e#NajC>Ndtk4aAc|JZWJANUBQN3jHF|=$|sg zyc2j|qrL?Km?Fng$}G#w_b#@~zUYa}F}q*M?otBx&78R^dYtBs0d3 z?gxwkQL+0VtWSV|W%_*)Wa^%CBDYl=HJJ3f6@BKo&)yJ&@;$8WwjY19BT4ik3Vszq zE!$vND>Z9E1Ac4{X@YiS8%F1yc*X;?^p6SjPus~Rv^*V+L$((uI^+nmDgiXt*8F82 zHi56$>ecpb#U)EcMhxBgZfz}I!^ag-ELFRgg~D$4LT~t{)xTDbsp)e-&9w=mM#uzOIgg78kXQDg809;} zAWvn&+YM5#rO1v4_-eL(0;jkH6{HVWExN9Hs*CN#jK5U#aVBI+>0szohIO3$J4ZpY z!SOa&Q+w%}?zbeqDp7DRyB>rRb@M+*tj4xD9)|4$g5XW)6xDyrKI?oT{CFkrrRAnIp8?aYkWI;T~XdlRw`0^#N>~P-|ARb(;_Q!*^78A?*U} zFtm2gf3ug$`K6|g@KKI*ytVef?GgUCQt^u%;0@{EdU}6)vf|Mw>?83@sT8Gh#}zV| z)%E^UgS_x1#(k6n(BaOF=Y-s%{-rmsZz=PhSBm|p&U#=~C_1_ec}Sm7Em%PL6hGd# z_A3(3a8m>!e2U-8^=OQ^tO&3!UT+UN5#l68K6KO{u8xb=?(1 z>a}n=1{Z&j6LX!dpV0uao%vhs`X?|yb_@u`;BfE2`_f;rR)PI0GRXh;2j7CKj~h2+ zbvL^vL5Z)s?Kj9?#|G>1b)_z}A8I7QnM(uTrny!w8V9ou5x z@Wcb9dJ*oeJOvk;gy>!=*O%qf4{C6nlttL;<{3v+UKSdiPe`Qqcp zh6de!4NE652Y!);UMRUueSOuqyKG~EhU&Jsa45&$Gc79QDR&VgonggZ#8Gb(QT%%+ z>sD$Ay3WgG)i_Pxjft-_x|oN!?=aTC%LD+hU^VL+$A8zh`$?Yq-0|1u=PMrs#gjVR zZmxep`k^%LJAoKZ;z0@fM?%5Av4%VpZTuKz{1HC`Z4832N2S32$0yOoFx;Vmo-KJ% zH3}`o%}ngz`UGwKSD98v2HqO+FaM3A3RSK;PGWroW+luTqwduG!q!Zy{JpW-u4CE? zb#i}oq*Jk$+p+LhAfJ`HtkkEN4f#ZM4)dPD8!yr-UE9b1{pdKHCY6NtXFVi(r zA`jaj`}{$2x&T?I&jK+PQ+cmiD2*}-P1ZGatlX+VfQx&vDa@^#59A9={0-aN*eHb9 z7n@nEDJpN!0^+@PW0xCKxN`E?N>xwnL(O$C8GIP>%pB={V}Gbyp%Em&$sD zU@5kH?GOVG6eu8xtv(mN%Ggw!Gy#9YP7~XUsH=1tHx@2G{aXoP)_at&C|_)b+^{F@ zfUICWtPC|7I79Ktsi>;1p47x&{j~?COIJYnDT%m+3Y8F4bi15OyQl8(v&#utas&(* zOpq483Bd)b9#k0!JlS>UHMQ>3it}X!s!jF`#r&UE%;dQP#L!{QK4%O1jdp(`iZ9kR zKT@XY{qex$?`NI^c5)V^AZ&joR$}>aGrTyWBo;!%Vrr4_QkTQ^ok~4;P1hZiO+M2d zaLhc>3hIS~s0)uXt3-hzBs`im1xur_K&?lWRS`KR_sV~(6tHTPSW;Ia6A3LACgFlKZ>oeJ&R}bZVA_}c6+1ad zt!@;wk#yWb*xEfDGH|7fA&W9{#VwXlaV2b5sL<6_JFsA!kmO32)VsksICZ^z?`oco zS|94En7pdDzZHoP3TnEkn`!%^*>4MmVZ0}9715s`b%}AtwE^DL4!(c+ohp*kNNGgb zi4_$VJnK;sE@Yd&aPRisb8J>NBW@>0>AR?*E+^h5LT4Nz=>EH-@&q6hTBC00o4nvx zil?yHH5;o%88-a+vHt?*TWbh%lZ^%DiTjwMQWJgQ?nFJu#hQ`dS^}=+%-*MN)7H>5 z)|HIKr;X}w2S>&`KAeAHT?by!+rr_1)J>M_xUflfpGK@OOxLIP7!_*XIFj4ss&x@B zWKnWl>-nKsi1g&uK2pRAO4UJMXVMxaPV&He;h`MLz2u~~tLtyvD7AFft@I_z2!&Lp z07}~zZ78PpKc2CZ#fSuKaI0_Ejko*-FMt_!s$M(uM9DR(MWTP8^>C29u4;)w@QtsZ zr5?|SKumj}KG{?opRmBB9GJ~YGJ&q{zEGbdt}j|Z*fOe@=;+v=AJfZnNbqUR5wET} z`p802ZgyyrX*?TY2W+WoQrDnLMF$gM(V@#Gw?+-rrJ~1#%gv=rNos$JER9I&QH|Bj zWL4g+AZ9v{S=E1nTHg0~*ILtb1X%YX_%6H;HxB$vR-@ z+{&eUNagxMrjm3G;=OH%>Q;U@UZ(j`ds5?1-&LWg8iu^QmT0TwN>myQ`tlV8NIjg<4WL>UtN;b|vsz3@u_0`sBx=Cf70atjv82j?lc zKcadX{o;RHmMz!Kf|S;wemG$GLV?N)yU{1QRL(^^Rxv6Wo`_;jdU|`rQxl2fNiZJK zs=<78W{6ye4$QwZTOxCbLTdm zx1dV{ABjj!b@+T`EKd;BFo|p#Mf8ld%k|=A?;L;ETHSf{G;?k#mle{{nVu5VJT_chgrSN#z7w)et>__6mQqVT%IB!7e9@J+K?4Vd^*or|KrmoT z7ItKHqfjHXdyX>UiN8r5V2uXMaI}9oL-*OqTG;lrYCw6(-Job01w$io zEQsl9xS5wozRzifkhJG2XxvS05Wtcs9B)Wee@%%GU zL48zLrq=bQeMQpcF6AJZgQw-1qR4nxj|}D;ypD^1!r+oKN&n~R_o0TZ&W2e34=Hz! zJwV?H*l!S~3q)wkue><4Q3to~7e&#Z{r*Dr>Affz6#5_WP#X*)J=7SNw-hREUM)L&J{#gWv z*py0805wBO7e!-Ws%L*XLEHmvw*wzM)xdRTd4bQxZ4BPav-M$~8L3LA(@lQhLT;O! zGxAd=+9KF|izn??JcBriQqp%Z)@)K4!p%C^$8{7Zl^gp!Z0Ek)(x%s6ue;uWoh{xU zsP+_M4HJ6UG>@YL-b0 zg1HE%9HYkGOg7GPF~EB$f=rSX>T^F+dMWp!e`N9LM6TpK;Vuq3T-)|vC`rw+s1EmA zFA*MDjdhBg#GlJZ(_!loZ>W z3OsvNoZ1!mv`d9X$yuoqYE96NSJ5r9qDL0*_hYhUS1{Y+cff#{Lz~X$B+Ttejd|=h z*9NxidH}z%DeGzH@~@rckOpf43(&nZ<~y6L`Hg?9bcdVK0nDo%pN!0JAKo(EAr0n<-C?<=OQz4Q01tVr?rD| z;Adt9d?iKqAlF~Od;N6a`wSwggF%e3V35Y{71!Xu>Do2xrM5Td#BEdIh;PM4Q0C5o zZGC@>3-;2$YuXJkhBBgkScC5w;MJ2Zro3#&AO6;2Wj0GuEn-i_q)GHmXij5FN(}vd z$QmOC-0IDrBMxT~KpC|89OJ8x{E)@qUzXFBmPot&3*@NX^a5}D{IHP6i*yyw0ZODm zjKigH#w=|3HJ7ipi`LIhUVxsgo@R+i2CRRTUqir~@n@@XZ%1ZkuKX|?hP){j!m#Ft z|7Rp=sqF%O6vw<+=R`fdmWNL)G|IQ3g)xj_e`BP+Q%P;n_c^qTk9$9px>x>5i3i2U zbcC%{tQu#4qs&CIfdxX;Hd^VyojRF!KB1fKR0T9&)u_LTrCoXqe&scH@r8fDH-LYM z@(qwL!g*RNx%j2@QgE7nLvnM8#_Tkt1GPVP>OeB!LRwSryuKRtjzEhksmoPIrHxFl zbLhy_5{hE~oKI$qlA8HDTdvg(zc6dW#A-h|@l8$o9!o-cKtw%e#h&9DzkKzLM{&!I zTIOR}hu9tWD7*01C^G<)6J)f-esRMYN^^@jYY-O}wwScu`4?q>{N1g^u zb5BzMD^R+73Ys+WYrDf-P9`SvnN?W zYEEudUJH8Y>5T|b$htuE#zw;Id(w$dvxl%x!462YH387m^pY3I%jwyK(aV3+KnIS3 zVXUlxi#7jFC33+TFcgxms8iuzLNV3?Na$-%?}W>{^c^E$mgF-uyG1uTIF($Dx+X$} z1l`#c-c&JJIiWiJqR)G2bFintL@wg9Z@b^mE?O&fb}vrR@gfSk?|{nGxS<;wTUxJ} zdM>@n>hA^4N`fJ}wJ4~6?g@YI5}wN76W~VhS;bv4ky(=w-HCqcM@mh@AxfZ*Ah+!Y zO5&Y|n=``h!m`eQ(Qie~K2_r^2OQ=aqt_9EPzSu!rlCx?TeJZ0_F12>;JIJF?B>t| z=A+iXuzdK*L}DJd)^JGJQ~WS3hzUaLN+^HFB{2Tw=b-fG zHo9nL50bO~jO)N#&8$R;Et$uVj7<)lwSrFnSM99S6D?IpD0ZQv$cmw_INKaRXj|0v z^^vmqalxYqs_IhVyTW&4oHwfrfEBvqoS|VUk2ezHfqx2$!Iy$+i*0?UepNF@JDF|S zK7oSa^BM-eY%rWl?DT(AQMi#7BZ9F>7tN@a0;|aPB!fNop$rh2g403C{8D7t=G&Xn zHM~cv!^vb|CY0gC8MKa9aLO?YLS-k}eiitSPSY&d&`sW{Qt$am;*P2eYq<14^{a4@ z11FePx$%ie3XVm-8e01+jAH=h&3v%*eiHz7EgX@1lI&khY2WB*O)sq2x zlfC;Mg<{aNH!VY5Yx-5J(Xn~^%$dbM+loh=u2jJ^kdq~{o=%L~FBGSx zOW(Tw%}l+5$KYlxTG2kOm^dLy{6H=N&_C2)MTP2+2V}czIfg$vu072%%RU@+kUA?P6o5=L+h z?Q|QGwpOr{A1xS%?T1XMN?DYrrJQ=^RI_JdM_*P)mxc6|xPM}86i%b=1+}<^Ku$(V z+RZD+gcBirs$HzAy2v}gjC-;O<1()FQd;l#%@$jjY<9aa*D-}d|AonON^=U5D?{&&fYn0GW`mmNXclSeuHNRwd^Gq4-9d%mFIulHy5 zpUx;fCD`iv4LtLv^6gDGd>Di|*?J4;EyLI17MQr50+t~uqFHy6!Beuv=g05kem|zA z{JES|*?n_0x2-8O#X(L0>PlkJ)%R{EAizz5%ucIHZvlujBsFBqbt$d*O6ZDlziS0&x}B88Aj|=ONK| z;Fo`i4xULTBWg8$r1gPgHzEIHek#VEg7aNcX+&N*zO6CbD#9|bGEq&q(%+6cl36^{^o!*?C6<4l?)S#bNBCwxjiYVo3#C|X^DoexY=%c{ zCR%jj4pV|jk^o1~esiYjG&j{CJ!4O?w-IdZ zf$^xw?cIyvQT5xY;U#^yV968+q4j^es>8eNnTA?Cx$)NR)rvZ;2fjq-es~d|kNu#> z$fV1z1@uKcF#LXmVF>iL&3L<>7kK^1xyx2NP{A_}3pM$AE*fXeeqV5X ztjp|syk{Cx8I5ERC`$T>9{^F~@8Cz#Vk?lyYBD)7fjNM|smI=dWmmv@(G-6-?Oo&pDtC;Z3TKI5vagG z30MslTEogpJ7V&Y)gfnDr*n!>ZcxjizU_H)Be0s*T^h-Ti`gNK%AS198^a2U>PabT zqo)hKh7)|KV#^xap5K{)mh^w`6*r@~i`zh=ABkG9FDkHFreZ&)@Oc*Jio49+0Y@1$6@NY5ix{n7+uLa$wa$YgmBQkEBaL?b3{1Pmta z{W3-*%J3ZqJdtjZ&fJV6!V47kde}FivaPFkQi*-)Lck||m86O~_>W(&o)iamOsNChFU%_fMh-Zk zGSfog$9R33I$}ZzQrJdb@RtIGS~I47;-*jtq|IqZ)(SsFTb6$gm@c@15RpRhxjiME z2iWy5H^{$O=gZ`?z}$EwLZNboPzeO&=w+8MRdD}fDPXpgX_}iX>mt@|?Kct&Gid&j zSqIq^x;LdqJEi(v$5SBri*;lB1Mw0_VMMJOodb8Z6U@V^*)A2Uzh#GjUQSwi()8GS zr%eHBxZpJ~u`Pd5K4Y+cIqSq?UGO~{E6L<`m(C~TVg6BekZ(7J$>M7D^v`WodX@eD zq6fd90PYX`R=4#b%I;=gfbs{?QiQRSG6Qj%wj#p!%hW3SX^Rp=722se4|P-2;0ilwuXrsZNxk@tUT2c1QA{mGTbb+kl-ylR=w>p1UT@;QI(Ip^9&_Cr}EpJ~d zq7smQ$5%*u@}XKs>2o&46@Ec!>v(Y!2!4eCv78}+ zhU23NDxj*9(tKuWqg_q#KR+Z&j#KDm-Jv^s2=?AL3o|s$2(+^+Tq7CPA;Kw>TImLF zC$8tDaz=kh-iWv-7@9-i4HN6WsUh7po3s$1nwiC;8+6PvD)?;M*UTnnh9u~ki9lud zLx&J2)ok5|3{oD_N(@a6`qmricRV?8bmeMBN@J&#ay=WJM;74M#nuqe(@=|OVCHUV z1&?)%KJ3mOFd&#-oi%VsMiBas3#o5%%h=`QciUE~=Lkhc6Uqf!7p z$C|?0?+Gb66t^@yPnJ6^E7j$Am2#1OOX04f{&jh|iPm9=v3bOHV0#jE{4x$baw<2j zP4Ld;i*^31_{6j&Khoy93l`0ou;XE{&Ub&m3StwxlkZK?h8|K>k(||EOO6;<`F+m( zxp#&wHstFm@JeR7XP}GK5tXB5ab9L-MRfE9K^&)e*<{mPp*=x36X8}cg%B*=uPcksJB=e)aNA=G-cNR?XL zT^yY&oK`;x$WgKi!9KohX3#{}4r!5MA}-g8PBk#6mT(>jY23FymQfF5>utv6~*bY|85#q)VeCYMI(7CaGIes0*xgfSF5_w zlfT;QH>D60+Y$*XeH`hR%6k=q3NM_Qpl!T|+?MR=nB+XN0!I3XNV;i6ekQ$vkcEuj zHuEaL11!NQs22+&L!(d=y%m3>j>T%L)eIW1em4IE)t8`Q*CtuC#>C`P$T};Hmf#(% zP&kR#%9#!AVO)?LuklZb)TTO-@FC^#?^_yzE8$}rip@Y^y<^wAxZeWG(I4uc^)M+N z94d|7tC%!BaJ2#}_0;<)6lz8lf9mo1az%ty2A;0w?xZ#4rNL%I4d{RCXhsm1a-d}v z_sTp@i$OCf=_i>7`KGGhbrH7@U#)J)W!CI6;u2!ixV2PehS`BRGIDRht< z+Vf`t>BYCY#U&TAAbdZ)w8G6V(9M63+~eXvf?Wb+563ga z@@E~TsYg*QFb9?&(OkH3!ljle*bgsR6``FX>r;=GboX4GW z1AzY7_;jiLAR7uPFI(3jr!*K4dn+B8E=m2l*bx!?bMc>aG)9ZG$E`ij8zvd#uo^qA zkjDAcoMA=QxZP-*xM0mivRuWT<9HoxGGsMBbpW6T4a$GdHu=f#K#Yui2e_qlt83Us z_Dv;Smys3$Q;{NatY11scd4PF|_dBgVbAM>QWg5qAJ*j}`o*ehcEd{=h?1A^-kGYFk zlR(+)R36{KKAJq;?B^Xy!}*2$TwanCnkFpm?Bajhi!2Dcyr#6ATnUvJ2TpCi(Di8g z>H4H2R?6Y)u4o8-f!2WY8%Bq{W;gf7lNuVyYtm7~$+8@|lY()gIqW+Zo<#88hqu@U zxPb|oHu$%(2<%OX(pjYHTm6QVX~h(0_M$7Xv1H=FZSZ_VAq#R=XnH(+n5AvG=E4BO z@jri_&t&d?-EURtZP7)TzzTy#$9%%|35G9QLDX5U5=yw57}L9jrCy_wVbf1YT3n4& zv(C(5T`-f!o7TVWhh`B-GMz>*?F(Om5uGVXBD$KmBV$d)(EaLQSi8;U{zlh0=r;w| z#v8Lx=4HzktYl5cQGYYU6n>djO_Ga9fP#N4;CcD3w+mm5qE+%MlpduMvuj0F@t$H$ zS|4IRpPlz-VGII>z?kT{(JA&4H=P}c!OU7n$fbmZj9i$Wfs(?c!t7Nr@)@>#BE8@n zA~FqE5ZLdn>qS2L=MHcKZQ*_lPvo;Mr0+iSv01f7SH3Mj3u|y}a3H};6#B=6z_EW2 zC&#*Gd#MWz))=tB`n(Nrihx1NKl@G&0f~)tI(XCB)!he34K{=_uMnk91&*s7StevX z`s1P+p3sJVQ^jrt`N(h%0dIV(KEK{)fW#oAGeCECBDKT3#UUU0k&z0hy)LiN^iBf2 z&Y$u>;)0g+;w8kOgo{`C;kdR)%dvl!OWE$}P>MAxduP^L;alEUw;nO(6}Nm_^#NI# zIZD|Tuc9N`UkAKNhSPS@{&hfkap77(=R9rCUkSE`S{GP^TKM?=t&1Q1I)ldXu+<^## zAlK;hK_WFoQ90rP9??P9j$4095z2$KJP_ER^%^Aut-aUbZqbbnX%TbM7!j9!NaYj( zIRUAtR~ZZ3;sW<#mV6=g32;+>3#Y$xjc04{9_-P0kQn_rg>Nuq-M#y{dCNi`T4wa= zNUrzs61|A}75Mg{A>g?6t;bMt$+W729OZrx&e52^$$E?f+Q+PY<8^--{!&}_-}AaTmh#arOj9G}ZCOQ#YADh<@mNa?^RbTk(|DDDE~v;TZAls6y5&bu z$d9u84PD3Xf?l})>cv2U=)QIfmg!!^t`_q%rx}*LF`UlaYwsmt)2*aJa90L&0j&Zr z{w!djDQ?Z4>U^=n?Sp?}XwiF#76=}EtsS0q%c&*K9?Wl~^viZ01PA+SZ7Uynik`jM z5}oAok~Bvc@D;=Fj|h?Hv-#-Usk2B~fu(jCz6@82KB_&Z9l%jTHbBY3BoR#GQ?xji zcP2t;Pc1IouZXA}1nb1pC3#X5bodTB-3)&Z0pm3kE9~#2n7n^EBCFBju+3O<1rb*H zWznN}L|N=2);@@TJg65|4O}c);tO^IJnWuSx8zKp)xfi_?=txV4j5Dwa8zMWJ9nhm zxz9OTK?phJP^8Ab2m6DS^YTb%hNo` z=G=GZJ>G;T(7}3rP5;KG`dvN5LcuIWH(N=D8Uo*QGunMyucYXAE^ z1zS!1dn4he1GPySsHOq{#43>=KSq)s|;Cj;_Bez6ID~VJ0W2|e< zRSB^(Kq!E~{y6D+40#4beiXBVi@&_bt7dN&Q>TA&kjD^*_hW;RMQMkUoZ2#16I;IE z1RZPUU6_U>0OY!Gs;cK?IW|aTN@z+v&l=XG{sZd5i4}_^btEYIG0fYxRyN`@6r?Eg z#~;rF;f0g?aGj|907WPkA;J|3jw1%V#{%|98v&7`;SmLbt=~>-iEpyb#k?~kDG@sG z$_sz+=9ur64Xxajo8;lq)|5EM$2pn#esTli?>-~8i$h~9@yd|pT3glZ>oaA>QGdou z9fr!xm+ngC^v5ERLc}9c1i2K}uD8`S$Ag^Of8bLTyahvzv}_v3>}61%kJkF#IW8U7 zzpzj!AM|Hw!qpRn ZXxZ|Gr?shiAQyl7(eK-=&h6t9z-xq%@B%c-Vt5EC|1f3S zMAMDUm6g|nVMhmetaZaI$k z^1JF$wD8Lf#;p~+Yp(OWA53KJjjgNA^I59*6Be4MyMDXeOJEx=b0lR;;*WDN9`hB(fq!VM1SMk=F>EJZ$2%6TIZ(L*p~V&00LY z)n<^H7Xc>(-3&EdTOKK`Jqxdo6_C?TJ6Z}oYdmmOjI}{lU@;-!Q8gF(%#wdz+`s>i z08s(1{>lrpsT_T79UtZ2Lems+Q>^Z_7uiKYB+nI#L3|2e=s8DrS9gq?ew-a3mY44_ zh-vdNa#{hNKY>7gxvZxc9mS7GJk+A_5v>7qUR2s0AY=Gl&!^e>aQ zspQXW&;ygPyJ5AJuSpW+}zc*-17JA~cgkr_eM*OfeV zMdpFa#P5hEFi|^X;6^9!FDt<0KmLJ(w~Mwl3-aG!sZBQ(u?94Rmib{5cc#byI=Bqi zXW+E}g*CLvNkCh@A<{I80-c{Un-aTLFIMRM6m+Cw(D=)L?yzS8pW2sJiBA_tY%ab)uvp{pTdbQ%IoUQA@E=j1qlc5WlQ$EkA^Dy)ZZ61bRG3CB&&9o_-U~8sZ1%aQ9 z%Wwi)Grk*)2#mm|*?+wp`h+-PXR$HIL8&poIt%jwYsH&9jO}n7C;a5GuGM)MKfBI1 zSOm@{SmQ8a7i8rC#04~D{agyUFaJkOVD^*Y$?zc-@k2hm#`1@Fiv7nk6sR6Ja>gIe z3gKPg`SHBBlizWB|DVIHi}y|Q_|_bTmeWHfAH z-}XOmO?qn>m+{`~^LF;Pzs=O^-)|Ra9xt}%o8|3py_x0bv-u6bdH(wG*^B4@ zcecEFcej1MUVlA1eYn29;2ziW%WdPjt`8rse`|g^<<0ICU_7s=81&njdaylTtajLj zXX?@X_MeO8<<*Xjo0)<+ygTKkKT}V4^XujLgVp8rqG@O9)oyX~9rmc1`k^1htG6@u zWXXMaA4(iDFK2)M`v=i@efI5_kG>w$c)7T|o2J2A*?+0Qp@3~y7c{7(5ymuJI6}jX zS%B<_1)nV+!Q$n^S8rZDIArn7yX)mN6W+!%lfWzKPcUIc1}?V3#eNKzA6`HC?qC1t zxxAWJ0}E%tscm_aZ(Ba>T)Jn%3v0|IKMqWcKIRiWb_yo}B@y}2U>+r_!v5mzk2=j&C@ZR%1Yt5IyFc$+EyP>(IpjKQn5$; z630A@EqQ#@ihud#_b(nj>3O_d-<++}v(x8`iz7<~S<0z($b0yxO1>Q}meh`^A0Ke3xCLBH+<$X1Zp00aWZPoeu=4P(0e!sn1tT5SfeWAA3^X--T z&tkJy>(xT-{=HVatIcAe-mmXAjO*8h+Ae=n+r_UuCNov5C3ieuU$0kODXHtlcB>Y@ z+|94m6ovCls3-zsfsa~nq>R;+R z^}YH*y-`1^cbob7&x;*Ma0Rk|%uIM&P|DK5=juW+V0Edk)KdMw z`dMA88?{nvb*p|+8?{wCb*Fw+|5m@L-_?Ke#CbGV3DiAxM!0P1roMQ0-3j>a?tl7v zu~UoH1^rpmb#LCa_!W>9Zh8fICBV&%la`m8iTW+1za^l5dfV4NCiMW2H1WU zfJf5~0nQ(SGsm&T&w{O*NeFyVgnynN1Js3g{bvDqG&eW|XT`ek$35Go&l7r;17F}X zAK_g3EbwY)xPa%X@NfX%!*ibn-XERI0%Co6xHyKWKM3NB`Q>8E$NBmWC;N<_H#o=h zHDMnA_40zx+?ak???w>8KI*_LccCz=)Q6F z-z`qpuSVVeVes05L>kYZ`nB%cex;Z`m^h&c3((j@k5w3Ul}L+7zmePC@+ol4dB(|5KeNYNlO(d5Vs%unb_ zgRWH7)#>p>G-lWX>VFyPf}uIEHi+*^@%PhrwkAB`22VIUIWhxtX=3D{s;$Pd9ZN-p z58Zgxxm06l2T$1269?BFUFSi3TNU3F9Q7EQ9gDwzm<}&Hh;K^q%~*UhA-);JH+FJl z24*J2H-q@PD*kxY+CqCX*4|XL*Ms)@U=@rk=?OpR!4Fy=9eTX=oEr|8n@c0W7r&G>-%;_>?Y^wn;@*_||f7W&2c)%8eUm+D`ZINCay+g-_|&uI&2o2OeAMynA;$eHI^hheoYtQ-{s2!n zX~IFT$W2`u_kYDLAGDcRf3WrqEt9bR5Z}n~&`+T2UhtI06*iztxAX2>SQgWrPx}^D z#l!*#n=&blTbQD4;~})c>d@;5FqXsi$ywhL;hn;0;ubds#@KbA821ebw!T=2CGA_BfwZ5M`L*m z%j3e>lZ;f;SRTvrxB|PyLP^CSwoOMI38O==X;GQ6fG88cF_XiTW2SM4SN{5W4Hhee?7dPk>$~8+z_>$cQo8vyT`?hHbfaMj5deP~L=6O03jKsjUbw`4mn>jBD5Cu+cweY~ zkXp5MR(^f**|vIvMxB0*rZYjX29?v0$pvws62Pg})aICyH^?(kKjkjB5<6qRhg<{O z^up8hwnm4}K(B@Yj=W+AgI4zxjMT*lOuH5~0Z!X~mT9wI~9T?N>CL63|Ra_)9x@KHo z8E{%Y*@54!*|M;v;S2WZe?`fw9Lz8MLl1VZfBbdT6l?A0k9@$U$``(kMZwG{4Vua? zR^cgqGeYxrt2?rB`?s4_nXItyZ>4WQ26gX)#XjZ9UR#*WgjGEDD12k)4&6*C9TA#m zbEvLn^}y1@mozNCSzu|KD_uh=faY)`e~_Bhip9LWU}H6Fov_)x2)3oC27}7(6>4=% z5Y?OV#EK~;5fgx>&`NqxHbb^u_NfBL0FO3|De8|djl+y+{g82Hcq3T&qCUV-w)FLT zQC+5HQJrE}sL~yHunN+Wf9@Uk8#8?=hB8MZvLP(k;O-z&gxX*N(h3%KUlP3j)P!hV zU{iD_fO)L{|ys1n_FwH}NTzMZ#Gi=|l>a#J~WRz-bEF_l(17H%pA`)&pv zWvyffvGBM*ac-Rj-w20tXg_cHv7zdGpj6($^OWJQCfgA(NkTO8e+LiHkT$_zy2 zkt?`RM2o!NWGdm@@HN48HM(!2a4cCTbsQ~yBzatgdf}V!)2aMf91P4- zHIqnT(8^S-j51sXDJP7tNCP`wbv%KbF)Es>@0ZpmGpkSQUvm@LBj)JrZ?D1XRTMQr^A{+5hmgOItB8wGg=9-7gB>R%6!)JJIv&2Qn@iKsk?X_sOJoc2MN3CC#B0?4>0-D#kv!rq0?PuS8$-U(ky}n+SowEg4|= z4T?m9OZzh}8#(vzh)6r8uqZZvnddO51gJU@yh-Io)UZX&tgU%lMz+byS>e z3DLc9iL~##;v5g4w9@|UFec}360-3AI@M5PmG_g5XRqRJQT zn)e>ALxzC$*B5Vchg0i5zCh;vh}6E_Q(CoNK!?WJ4@paUJb4{oH!1d}`WgUHDyN+2$zlu!>+TAuJM%!?*pDzwd?uN?JBoguN^{ctathk_GyZxSd=*fL^ zi-2i%v3J!!l^FtFvD3b;E)qc}ci0V>H+Xl`Hv;e1kIbFfZ`d`q=)tvE18Ogv)0WtimLWDK$f=eoy zx56N7_1C*>BgkDe#A~WnbJ=c)y(pj<>Zx`lev#2>NP4kl=ooOXqed1cr$^>8twA?F z;?&b6Uh2Qb>{KrwkFZRgrnGv#VwN-A0!(Ork_hyA(swcGx^jR6=)36qukFv{QO~`q zl}Y8^^1b1Pc7gb3T~bvG7D9@To7Sn{O;m5$v-S7@Mr+Pv*`Bux%ESDtrX!}q-0YZA zN;(+#zJE(bEY0;;LMNNb8<|b$O}*Jur?vw%xNdF=eTp3{I$2}sU?`|OKPIUXiUih1 z6TY$G$Ioc#hadXr%HjU*=JKTd{m;kCLq$2MC|`%* z7IOoAVr70~n^(mzKR+(BQI3}Bkb?lTO%6OeKTG#^!C?t*;_;Ohbox0VCaW@^%EQ{0MZ1d6CD@6_6NM=k z#~0pzDD&O|J?y)7HbiD)f8OO?5sKg(t?)F zqP{dzKDaY_V4Y{oc+r41jpApH6P$oTvBElq@rG#m<{jQE3Y|pB37CnQ@_f4GR50| z{P}+O{SUVvNbI)O3pBG13@qI=TAd964nuzV>vk?>D+DMgaEvbsw9bSouAYRT&41>G z_-~EPZ*`1}9PjK&GJMZsdpX_uvSnFjKOmI*;#Q08$JS;{$dOAFce3Y2#$(#XXKo*V zFN7meNJ3CFh#x?rP&Xlx#x8dp`4A)EbkD#a(oX9SVd@^JDz zbrFBMs(hA;^6FTGx;g@_F0ZPpBBhMNBIU6%a#%Tak}9i)l)A$AzlT6iV@Rp~tivPa z(0^>Z=f|}w&R@6c-b8<2QZ&&^U3^#j)Q3l`yQk8p;B!!7p7w+(r-eKA3pow01Rml1 zg0aqm{EqDl#v&%WAuf60CIc_?acbqgVg_N4Tr1%PFAOld@Gj0*U}0wOB=qES*Ja%y z>681pPFkoD=^H0W#fTNk z$bFc)5+i1t*-Wv#t8nA2Yj5Y#F8T)TO0PSradMvSH@U`+DTx@E%_8ZiJEC!DUTECS z1ITaYrf+QfWSxCSVRkAY#?tmjma$`UvpYR#vaf#miqAQ@ahLUi<|gqO#VaEP!&gr> z1)s{ZU&uZQW)?r5r1rGNWqBqKSP?FUmodu3K3dc7i|el5uTK6tik`^=vuEhIL)98lY1Do~Vi1 zs@-P2m8gGk9VeUbPe2rEsp}$fNrtY8oOZ*EC9>yA&c4A!A7=2X1Qn;uxR>rVu>hKv zCG`8oj^#aC=_iI)f9Y|>d*7e{^Nf+XYg8wpD&-Fd-ZOXRzBVz9%X?75lejoBSNpzt zcE7y`(?T2hmCk5>OZ5`KcEx!S!esSEFPAiM?o4V{8pb5MaW*4(^!oCtynRfPj0DQm zwUaV9MP!U{ie>LNKSjH$hZ6Jq?cE`0GL^csG6@J{$ zF@tGJQ4C4ZI(2Ym({34Ut=;l|s^;p1#kF`N=-J!h=5)1O65-}xLU}k7-&oD7Uf>U9nhvXPVvH) zVKoZm#VM4~%TBu>K{e0F6)oV!l1%j82kW(Ip()I4;T@hY6JLZtZq0M$#n5^&Ne~^I z$e+wv;KDv@c(3_4osk3P*`}f|d9kk(Lj%be=9v_uFKn5r}g`*8Is(jg_^5_V@yX72ZwDQ1;}AE?x~6Tff_po(v) zeuyn#3Ju}tX?!5g0sMH?MAVM;#Hep?=Ckt(w|vbW>fVDf+~EPXBfew6mAlLW$J^|S zrVd|%`i%?AmGr|4$dAJCVVIw62U{K96asf3+qLmO3O{2{M=n#4T$V2)zlUNB=YC;$ z8;gIx=3hoyix)Oql@MKSUN#T_)w+RwQNF`a=Nzu8b@kJsv*n<{Z;wnz#C#m z&rvd%W80}5zRXi}N8rYlM$Lx*po-~t`Hw+Tf6c-l{-%{T{i6kOyoPy~`1})qWX8W}x!MQlbvkC1^(6hl!FvI_*O#yJ9Dg3;j0p!DOPzgY zH1X^4X8R3ukgrkhmM21vfvrv19Gox@GAGxuz09UqkvkdkErBFoDlEaYFg*wdboydL|`bYE#xbf@Q0M)HyI z%NkBZPB6+9FZL~XQhwo4`l`FEc5AZ)aX)PN$jf5W7iEK&GB z6Cp__mcA~3Y;9QdLYsZWM%DH&<_&^q9E4Btyerv>GZZ!uf?PdO2GKmU;dCOpWrKWe zd3s|gY8cswcKc*mZARvl?`$dRY5=Gy5oZo^wdL+@yE9G(vt@RRzPQ2f7L{THbBp1w zVGbaAjDv!0c~@gVUW`|wRlLq6w;7@-yXTqFXD-aMk`x4||; z4917;hCkhY_WwnbZz*uTY;raUxC3ZowtNu_*kuyHY4<39;)4XxPq9Vvuw+CWgEyuS7lbqJQ5((L_y{L+)!0Ow{1q zoq&b_Nz2L1wLiWj^KX{-1J?e1C)m9{nIsZ=BxYDY9#1-H)X*UNn}t3_mHVSn{dc>U z@kOqK+s&2|D?%8t15E6|r%Jx>u>*eEn4{@)ecHybR*sU7F5i})pX<{yw*CoM_Z=Gk z{Gi*}D)->o32z^uZ+vo;bguKbvh-4T0Qs6-ifR5O|MlVK1YPda597~zfB1hH2@gDK z5$EoA)#`9fwtt(d^eum%uW)-alk2nDlrdk@Bppa}7xf9@>6INI&`U^Y;A{&`_4f48+mH!Pn2n(bgTpLoz+> da1dWVTOYqbA4ew$5+P42Wrc+XV{8wr$(C)3I%JY~zmYq+{E*osMnWws$}8_m6*{?6a%ZSXE;kRMo^a zSNsJ0RtZ8~IVcD-Q<5+tYGXHOC8mr)gPgz#}jk@c-r}xuPlnv;DU=CG8w%`6GmWA0#Ay#8Cz&i5yrE$HCw$k<0XaR%` zi$I%c$wZU7AIcV?dDK3TFekv(BdyZ6$DlZdfq9B}iO5jHP|Y~WyTLjT(hxznTPG8T zmn`kEc1cnGDDv=%f!b{fMrf0IO%|NJIi0I0fPR$9Hto>ZxmC5xG$jeNMl%PDcI#h* zmK>4B3|pot{POosIa8r=3tgH;QFm2T3mWU$%4Cb+`DR#~23f0Ul)=QRGL*5%v}VOI zbW8cDPVCZ{g=;?A@|)-H7DJ|KGlV(i_(O^7@nUv)weCnQ-8ZwZ z0ME4J4vu>L65h-+0{hny+MVr_7te&FVTUY1HkFR2uXFsfr2+Y@q46;a!VGhqi>XgR ze%obW4ZA8NBR-+vAH=kNBrtpLUOyU=_yag6Roj}Nc z#R-d{LO7f*DJY^jM5~NB)0P0+tY{&C^|wRoq7`CX351u`qf|^`)h0OZJ~S?8^1U&d zBlfhzjk+i^hSQn=NARdb>1r82A0BQ6$FxbIfeoI`QPk>eaktZ!Z8&KsykDT5sF#gP z6#NznN71On&gv}XQ0TixD>1@3N1dFFYNdjwjY}lFjdfB1ABWcnM2=HZ0j&)H?qM1cd{>kLNq$@H$b%wV5bHAnJ%my3^+5E2f8c|3gwe zDk=y&%YR!vsRg4Nn7z>ylLi==BgqIAJ*f!m1CxV`h>6JF*b0V^4~9|J%+A8)HxV~C z>%Xl{4XD=GaN6KN@?Fu`O~^`SVgQ3ORRRZel`R~b_s)eXCkuu^cFHA3oi)H4@RMD6I=6fc!n03FFb4EUu;#y*$~#Wp=BcYA$sw&cMD(;Fjb zKWQ25NvCC^fGSHSj(ni0Vl~Cc7#eeC$o1SWov<4`Is?8EF+x51%Zbb=+P3bY@x^Ee z1wG3kNAHKZ>7jALedS~@%CSt^Vf_;u(9u1JsrKCy37 z7SK)AS4!0HlTd3uGVQElcJ%0`y}5R?(Uf66O_#eWt(IC@rT@oHM*DEOZ}BCn%W77r z0vV}{+nFzwqB^G0`XKg3!|i^U&YIVx9v2!Nw?u~?NtT#75W7f>DQqD5Hm-YkE{xwC z7+OPmg`i7o(W%zN2U~4(=FD5Z+e@8=9lDH-1M9DaPc&HMc!4satq&_}{ z31qxGPy?2AV%vaI)IA%RBrTN6^Z4-ZLETB$!7SyJ>F@pDabOG%S^i2FdX2kAc7Sp9 zAW}u84lg6{510tkpirG`#VweSFP!|W^kQl!6;l-z{Kr)j|6fE>Z`!ZpX#hNJWH*>k z2%68#OcArIOZU!;u_b@a7uRkdU#ABBT2X3{t_9>!92NABgqahj3E_EQB{ij{Q^{qe-S>YuUR6U%G@Yukj_`e^W3v3iW_ zYu`-u5-(pM^o6t*VT@KmS@jnm@4SMT_R@BYbn7<$7v){B_YBzEKT!M89e{56zCD#{ zIj=t0M-g#e`O~>iak$~rqh4ZL(l>_fX}R~TZCUh`F3CYP(w`>T{!Hph6Fd;UUuKMY zjG!S`pd~ZuE1k@xI+@2z18XTo0g5GvkUqa6Lhh+H$q?}en*;Ghp9c6Pqi52%GcfA< znfJa`Ocg5QTx&M*R+K;>qs=|CK6~MWyfOqRg1Y?~slWgB!B%^^p)DmfY_0K*5T+b! zGKd(1xED|OsaM-JVj*~L&g(-DLC|8*}(3^ zMq$HCpBffYGByx$S%&mzDeP$&kpq$vfA)y}-Q;3G9$aYQ;8Qfpw=f+gJdA5rLnU9I zBZTp6FsjnNQDHbr=m&_uVYs`N19nfwMhOF9{9)o0{zNJw?Q%sOslV^@Exvr4_4^uwnv^4*3yy{kv4}G)tkSiOu=*g|tMQW!W;CqQp^GqN zp(Du=bDHK}%i`j;6q%D>*Ky%1JaYw*-PK{^x{jUYf()nFn0S6*)?RBM^=ZtlSGq(r zR%@SZQd?tqVa-T{Lw15g+Sy^WH>so2o5k?5_;*@ftyhpYC+&Ue^r5ICcgA93%*NBW z%YD6}Vn<&7xHRhSuxM@LcZI&fb7`T)L#?^ShFF{#Aio=i0;3JHl|#N_`BNOw3i$ep z>t_*2U~OC&9PEDJVBA}#T21X30}I*_I+ss6IYz`;w#Rt5>l~ZE1i6YzE%6h4>tM@{ zu^y1JHhOhPW$JMj*i|3M(Am>zug;w|cTQWkeU3^7*(Osr{lf3ey~i?`rHO+9q*NwK8-KxwI(%hvyT+nYp?KzKu6)WGeSwT0~=C#YK@F#Hg$rP7`7(j}9Qzom`C>eSr>gmYNp&BbzIt#qkhQ-&IVJ=F z*i_=RtoizC^T%sKg56B;Wc`P#MXAwE@JjI+N;}B8Q3GS4y8pgk7!A|bEmD*S#^E*Z z-}_4UBTBEbEv9oXy{BdG&|n*Q-jEMVUVuU&CfsF4T9^h>e{|KDuPbH!I##PMEjPxSl3P!KO!qrWOc<>l$9De#B8fGhKHH!j-v+?76T^ zYWMOj`s5GC`T_&Qm+1}uxvfS`=Gy$YJM+`V55G?GmJNdXt>^H3i;w*Z=00p$^$zAf zRsvaUSokrHGe|}(@H&*C3fa-qZaY;=h(GUV)AE3WJiqm5(5KG#nbz9Jms7)bK7qI9 z8bO6r$Wp>94?k5#iHSKQ-=-f+W^CZ$1MARgT*DzY4Z*1KY4bQOkD)45Hiv$i_0$a` zupvf+p4EfKBj6l{hv5@Ke{``?lgaUViG`a*GB#&I`RGyUF7}$Wv$?x;eryHDF1V_( z^+l-M<{!|5sl}uJI5aR<5-|!I2s8WtLF1OT&Od0x@SCZf-S``nMyoFt3Em~dxM2*L zX54~%DWiiHP0zdjH$^fr$sF@x=LJu>fjp##Tni2BRhUeiAp7BN(_@lK6HMuLZ+~iO z*kJpCY*tK$BB;_cPcu(UB>1?0iS8AT!Qz31y|D=|CjHld`>;!+tVVNrqp|DR2tc6N z)2d?86-!#epw_Sbbz^Dx1`|yH1$+@1T}+%Nje$`B5EFyBb3hs(s1C6jFe{B>9xfjgBiZaEwXE%+>tr zVzclq?*eV*N51q)ffPC953X>Iog^E~0&?5{B%}}>574X_>Ub-Xt{0PXFo0%TzK!*b z!u5U+a+!iQp=V1MNn8db?M2M0e#~lC1*l*51Rj_`1{Nuf7iiBAQ~&a%u5YcxN`G?e zfq}IaNJnBY9XG9Q6!3E!z{fain1*2A?T<8#uum){((2`ULS;tlLt&&LwHq#}#P#9x zvDBT_*6v=jvVZ?D)A~|^2XI7Zpb3MO7ty_KA1>CL-!)@2zi{=Ek{OlFQDX+9__|m#<#y)6}1$Jx(>_?=+Jdb9Ko4YdBr!{-X2c=hp;`+v|b3Cw%0h z-nIb!P+M69usO#EM>lh&T81}QBC`^+U_Ug4PLG_e0GCFimiM!;!@wdkfVkO?QdY?q z-+M>#iVw{s-hA{x2@v@=PeBk(>CuHoMkS!!@1pJ`pPG9}+l^uB-RMfg2pbtWTiy;d zh3{=3?Ka++=!(ICV3e-9#H_`Q7;;h$rC4ppKF@^vwfQye%$7V;gfA4!C6%W%Fjz29 z%Nwc^N;NLmW?{`r|B^Js3!9QMDFb7o*;U`t4BJOgdAIpt957)9!XTPM=f`nz%O&f+ zkDrg~qX5@KDZEpN(#`%d-afm0YFo;%iRwhMBJ?8Kg;4asz8&YCh=@0D-v%fFYXtAE z=~^U^RB%brg9PV6Cv*y~6FKjBx$`EtMU@>UFj&qWBL0zbdsqJ82WMH4d2gHjTjo-Y zkJ-}cw2gI-00=i@QQq63eE~_VbzyImhJJKFygl0#YDCk^v0W<~L&Un6)NWj~UQ*A#gA*G7( zN3YH;*AN(`=qJr3+2_~|V5lNggq>yjbs$q-OvWpD2tdWO%roO}t0^?e9PWbrt5D_~ z)82{#XQ-t7Wcy5~xlYx_2|^K1|AZhV3G7vY(4_91C?Eu6BJ^|iJ`26ngFm!eKK;m+ zDo-2PEH~$CNCQFXXqG=LkfilB&yFua1EbNXFK>{ zF%1;)&72>HpzdI##fl13;~ne|)|W}^D}CXr0|@(#A&<$Ijq8q9>!LPzG%(qxBBF;_ zyPAq`>T$SQq1|Gq;clJeGSdtXu0}aMnY+QO_bGp)FC|NjLnulVgrI0=!l;niv`50S zZTHyq1mHjLSL#}8mz1b+abY)xlSMwuK%28aP*qyAK6}$Wlf{HM2lA43g|F#jh9Js~ z03u2tpYCPQ92-w9K1w=lUFvVen4XGGkC1N7gmaA+)+S5w18>7~O(veqvpR@(86jK%uRV+S*tmV zX?Gnbd_l=&_1m0*}?FhV{097Uo7zFR2{mlY?)xY1yH9R`4-cj=$_6ZT+ za3+Ocg@4rQsY|yxtyOm5s2J7@mk)Rz8>S$%1M=I8`LXP&39Hbh`ovi`R-z zX6W`Z<$P6=KhClEh@mkl2@mzkosHDB%n<%a5;>4Z=gPWWRak3Q?no-_0w~`P0mc%| z?E)flWEOuU>T)_$abEdK6jCr+IJR^&=EY_ghO3DCui|l1^oOz4^td*R`A*M1Ynq&F zD{R*BWVEjyQ?&>nKb^y%1;(HU1)cbg>CQ)5Dv)mMH zrr#pcJNvh>L1PwjZQd;;0b1$30a1hsV@Auxt{eh7p-fY6KU&W{TtKaPGh>`M7B7?u zC5|ls6wBGQ-qp8n+1hzb@=%3}6D)X$OhQ_i?{V>6oLqrNds{`KcqXGCjAA532n|lL zmve~1V4Ann_t5T^IYfDSB?s;dc6Uwz4A*xngIharkL(j(%$#FeB6hQNfJfUgk>?sg z$qC1??S09;Q+9_9-Vcu33Y|@lRw|bd1RhS(^(*!7%ihU?;;#d(VGhcRMdtGrXQO-a zt(QQ>IE&pU0GZ<&6O5T%QWGi?CO7NrFVVLD7v<yZ!rF61cbjj-FwRDaYScB7f}HAoi+A zqCwP~z=Obr5s;P#?*k3W+;InwH4tueD?$Ccflpm2mHJ@rZTeLvI)assMJrIyOwd&se=9AxmZt+U7O?r;4t=XSH zr?a8#Qp*xA@p@j#o!#EK6$d=xb{8%Ah>F}`NIzMwTu45>x^~FOx(b<-P*u3%#yQlUAab$H@(8&L(KE-_jtPN>QWJnt>X7Ot%iAH$YB* zhLW*1?HP_G@t1wiE!q>>N;vNEl<3U_8v>@*VVDv}XWlOb#sx!EN$EYz2{uoq-VeNL z62Z800I;~%v+K9r{fW=LiHITUWr8-9Bn&NMIHf_4F=Oz{4PSKH+_oM&?Q`4WZSVbe z`X_(CH@KsYlC*XtP6XUv6)@6C)#^)I)h@Y~Z!7Gcw`)r2CK|N>*QVxJ!$2}-qGoNU z81U^G<7zDs?BWdW{^)Q^`rAT6Nl+1R$;5~hfUI)BY-@qV0C)nLlEkhs@!;=nuXMWk z{-s+L1smOi6Y=CLdf(nj*jBYnwffKG;(&!qy2u4v7gWu?ML21C!ti4`;{a4Pq)C{Q z3EF;MCgp%4=361dY%VMP>n3_Y0bYU1uBC}2yQZn7uAp%I3gR9M)hrQHb@xUJGJGs0 zKyOlD3M%IvI}PG`%say!1ZW^M9@L|sUy;Y0CYGugRH~JddFU_jS=V2PL;vx`S%kJf zS1ZZmz{xnaHc+}q2%t3`!k^qU99j`RiM+#Wj(*+N^*WL!0+=X!q!F#GG$r3ws7p}` z!~QxKr2v^7u_K924d1S6wh&d)A{^2YfLuIx7^q42 zU8vQ*yKg;PWkMcW08hdLZT#5*Q!1H*zcVC*B_udG>TRN_Z&^4MwW_+r6<6k)#CSy|J?Rdv>u9b4VM@^55f{60(~4g^Rz;kWlSTRR>@|xU z1F0k{oES~~!!-TY2g%%mE7d3^ua z+ou46dY}XP=x-@!q1--WUunrx(1L(ip}5j-rPF#wr`=?+EY6tHCWrBPX9C=p(dD5U z1;56tv(;rmn3(#h{5w0I$s8h>n0t={eiUUUsZSfuX|vx^@RTj<9%q=}027`S73s-r z-j&-tElw8IKN-5kV3u9e=Cb|ubwk%nOR|3`{e8-C)g79K=J`n#(+rrMipJH|Kh3`% z@Wp5Pd}I!lsDRS45;qd%y0)hn$Qbngymb<v!f|)O51VZ)b{zmkfC|0461vYxmDB@1_O>%L`QsBc6?WG&v5zOMCHTu& z$wSv)-1&Xg#5*a~EF{T}E7YEZUGTpL6I<4P%^6222QnxAE)r_5S<`2sNFA(w$Iqp< zadirzzVOrJAOOVP^QHI1HWZyN3~E56Ayu}ds?K*LSaI(6Db=o{9SsBpA&f?J^b1oa z1B%eq)OOhU&cnKl8f*OFs)47munQn2*7#v!l8i5nM$n)lQNmG()U0 z*vW!oc95!R1WuQUs=_2E{=qOTuJZ2A01Tgz7t>Mm?Q@WRR4?{+?0LKZRPj2!dZ7~# z3PMDk>OwGWH{b)^g}=8{_xD0@a;14T+eA~&nXPO(kDk3+2hOtS>Nu&N2D#q_6!?gR znuv}>$yB%hC|*Vi!Zc&OO2a_g;cxPmN8^mX#1>sAciM2_B`@xvEE+K10#X)Z0GXYx zEQVIOO*MP-U5`szjhzbGt(T2|)TOtAR{ty`dTM)-7;;e+=C}}d-?2LLf|@z}n5jDC zO^BDnl-`Fqb1&Z8ahzHC%osNG@~4@{8SW=RIGe-?8kuw&JKx4Wn|-rql-xzETxfSX zCvB02y!T^F#94as=c1okO>7&`0NANEvq!S6G&!k>cQTT3*yTCTE=qF?aBro_j54|T z&|K=sytY7I>eTEo)F7hveU6+_8Af1%Z1kPRIZ6BsiHF+5T502|9xVv;NQSV`5EG z%HaYu#CYoZ26D1<-YLrZ2rXDuzrIwD1O`GXOdw2L`V8&@!5y2Ljv1y{GA&9a8@}Wr zCC{p+!Bqvxp=|a%w?DY9OBN?dH+O;?aCkabjO#C|_uRfMje?iUx4H?Jr07D~=Q8ci zsVWYmU4pFHV7I9o02QXsIRNy)k(65-{n>f7P@WN1rxjHl@<+-Bz!F4G=F5K(DAaE(|)~AB7 z(Jaj$r#Lf^SKD3d9^Cw|9zOj0Po@N2_9+j$mwbGS^)u5<^^48thLN z=`6hOdRC7IH%O364?3VO(F1a^iptkgcrF9Jfcg(&rK74ye4DAh()n^^jHOt@@lHDS z8$rV;CgmZf*_Li_T904-Dgda@^@SPH*sZoM)-<1A2i~OEtVC(hXKc92do?huToZIz zyI^)%{_c^7QS{(_F_>S5Hh8A=kkq%BA4qs=7rT}>pn z!%~1WHONsco2@@b`=?8lOIGa31LC-DB!&pkn;Z0!n=4zuoA5URE43-kh3g%%@t~Mhtvlx*qkyp38#D79D7c7Vz z3af^VF_%V{(nUh6pB)O|^GAacB@Tnb4yu*~+eFhjL5XM!4vpp<5q-BzI4ZHL?J0~v z4$I?(^s}K^2>^>P;bN9LJTWm!;PUWVazwAU8|=lpZxE&vSvycBSjfQh7!bjP>e_<7 zvdXk$P%{6(hFN(`V?QAMgohp#x6LQLq;EPEU$cX_+EC4mFCwX}sgecufUI(6;lxEr zr_57VsBse>0Q!KGk@_9#j_BCc4S=MNLs3KHXlmMU1AsSJcKSsk7ByE$Ha6=^qD~|8 zmQNu8%SqRzs}wK&$+$SEq+8;LOMpY}-P@ZW2$>Cl9=pI+8pcpzX53v}FI_%yi1F68 zZA|Am$*0Mk{FS`}q&#|%k0jJ9@D&dcFhjU-qXf-K3*c1y4f3uqg+XH)dGL_Wn1_Vv z8w&NT1Q2>fv?=U?&)>R!XP?jWa{Gi? z9w`80BxpNp{RYHdH9xAb>vSB(GO z%bIjE3(Oo$ah!aIo?W^Lv$~3g!w)`!Etf1049c}UXyK=7Q>-OOdb*=qick$o0zjLULalw_lAV2hQV^J z=qU27cYNWW1!Xh#93J&fQugc|DMR8p(nkZfSa-C7$L}bOt-&aV$e7Fh3vP!U1(U-l za%{#VR{a=H$pGtL_|%K+BW(K(+0l5*srHuZ;j7n*rTFD z$p`Z&aeQd4;EjwgFW~hj$`HkW%g7K_`(?}L(~=C5`Tlu#(gTI9MoRKaW~dN_<4j_< zJgOsP7^~(f4cUz_pGU@)={7Z?y#NNN9OwKiMDBR#1x$GA4jV{i z;I($xiEJEsXD)h~B)PQBNMc<7!spF6n(aydPE?BX=A|qgXtHzl4)pbaY32NYrE(S6 zvA&y#eRHA)EGg&VqQtfy?3kf~q!&fxFQ-xT>K-4dG_eZ~g-Tft_wT?!^2LTIKVqA9 zOEV>21iGH6n~45sc4|4^ z*jsBPEWwar7-kpnGDeCYw4pM6WmaOqP#4v!M9MS@>2k ztGH0N35|%6Tsta*hWyMSIcQZ80cgNTL1ts+VyymO~KRet1%~zz`YBxL3)wX zCG^Cl8`Bm^xZ2#Xkh&l1pP+t(a0@OmtsO*Z1{Y2<6PtYL860EG~7Gv9`$%Ew{P<)*|F{+jkPAb;ec>f*zhY)=#I`1Lj z1kfE~7`fxA|J@M6`wSe*XKMz~N-8j829OKq20LjpXk1VOX!C2?wezMH!z zm1pQ$Q(SNumPs`*to%`tfG)?qZfhoK5db}WMK$K~OsLLvYC9(mq{&53j0*d`Ra-Yi z1z5kRTL#Bm@&gEbke>0+m@W-v-q^J4A(I6RL4aWu>tF)EEi8A5FB?Iy@~s~Z5qH>a zHX7+2d}5L;7a}_17vBp&cBHu7QmJScTPes8WP19-#5qleNnAFp0uEFbHRX#62cT5* zkm&~mJz5ge>53P0GCW*K1>eKb--aMKKrS%I@+~`X4=}?1qil+Tpp_hJsUWvFk^4eB zBazG~@f_rXP4YdLp`&Pfa+O>Aj!Are=2^Ql~h8p4@m6#0@`1lX$OveN4XQerBTxt8i4*N-cH;B; z1h*)1BMMr4aD|V_VRH!=g`VdU1-g-*QzG4i@!2~%Clk1Z=8Hc;u4kma10ZD^f5K@+ z^ZyACPVHA=MURQvVbFLE=V1`8k@jOj4GYf`%!S(LR`g2~Wn_~N{v;@IocDX1rCzsf zd2Uo53nhYLNdP?T=%x_I2TeF(NiPIqo#zlpgZEL_`S=n>m*gmtw54S){s;y;iQrK5 zXn2kiaUbKI)AXu0U3)z<0Sb$;GAV%{YRlRL>rYm7?vPCnpn(G0jw5zK+jOgiO44>M zh|4PSUEc|wA4lgkj)_N^a}&X?Ly+uF@{j~wGO-5^%f_w1rn=p^lVDmGTDj{O7HK8O zc;F5-rW>Qa#QR)SF4fSdAYJ)+!#w_JMOCa{H2ZLl$%F?UCH_)L8dB&h_Y1E4E%>zj z+NhJBn;+L}zMkq)`G2f0K19xclJaEHhUXJ{lO%qewa}0Yl%w9=G=tNfcPVHycl6Nc zQxJ;Z4eGeIR1@C!n$Lca7sS6YfjJk4{|7ak9RGtFZqEOs@mDz3_M05{oq!Pk4+m|c ziTmOeVEEZ}M?~?1k{U-YB5Fmo{TguVVg6sZ-i~cQ+k2v&1?p~iy!Dy8hJ83wiG!Yw z=2Qp>DZmJRT<_oer;$033{T*Sd=&_94FcRM}r{cL#HoQH4Kv$ePfQWKwKOu_#$!!{?`0_FPoJ zKPLXj6Z5<4(c0jA@_Sm4y#!xQ!T6~je{E$UHqDvG{q;qd2Iw3oVVcouCx&_P_SX1D zG#dfBC$`o*KnmYRs~2Z}&Nz3#O1~5(5)I{dvBgtP0oL)^MSIFX$T)j-lbxF)PDZ(l z0*3UkXkOx2b{HaHQYK<1CBxvzXjMM`d_P7uF`hH9q*Si=*<&@7yi40d z%~D8V)vwbpAmMT6+zOh?8fbW6@ePjUNUc8R4{7&it{Cu*t1HxMTE1Oy^rxT@hNH#u zKcsmC03}%OHMmSe0~1!B<=t|F&1rK~KDE#hI9)N0D3M)lE^K&7d5H9{v*v0liYUc7OAy?!e_cP}|`ng~9^ z1Lox!TVCpE1xe#C`P~|pC$=1w&E__h{L2Q=fSsg2aw@I@v^b3h1y^WHuDrhQ!0(lK zc#?0lnpqoQ-LUY*kMS8%HQEuF*PMSiH83VK&9(}~HS)r&fqn86m$W5mbC;675EtnD z7M+5w{z7aZ@0Uebn$O?t!m!%$0Tn4%o0qTXydjvZ(=}QDnvm#ajImFPF~eJpcEAx3 z0DSkP45N3j<{3dKQCxd^xT-V@MWU`wzcIEYkj2XK-Hf)_Q4YMacg@hc_b zyzLSmtN-gY^eBWqtJ0@ z;P=;sTe)TN^G*6a_ZZ(o`)D#WPBFEO(UbVkx)8CE{S7zmwzfZ7=SJjIZU>kX0}xHP z;Ct~yqL?>c3Ii$1()I`E^OS0LRxLLNHF0k8e6Y*U^&h5*=zqGns)?ip44?ZeAXdWG zys@kg1Dq{lC|P#{&TEHSmO2Qfj1FTTo2UqW7mR9Bzxo$aiIS~}U-qt5)N?Sah%%^m zSShcFUunK%xcto2a1CV zoyp`g^=6?kTu@|))Xf5opc{Do-zenBMtFC0UJ@_poE?d&qrKk~cyG<*PpRROST{M_ zabqX63=0-2huB#<3i6WT$C#SFnwC6oGf4}l7YWC%+e>eR2623~b}&i+{{7ERJNq6V zOPIAT%!kfLf>670GT*lq$H($YdG)qn!;dbQ0}05%r{7Be)FEGpj$o#LJ8uS zKK8GqlS%!Rit`~8c06Y^@dMKC{LSl{aJss**W~-V(KoC;(|0Zdnl)U;T5H&}%7{VK z9{=jzYY9i{B&E+_M_g1bJ zN+Si*eYgZRUp!<(F>ee7f8w02HLQMORKyHYgx|jfpt1%90!O-W>3)kTrl45U{?)O! zvP6kpqx_i5%1dtC29)^C3$&3vEvI*uZ^Kts`u9{`9DKQ7%q4=MqTRe4A7&I@%z7r~ zgQ@&*+^_cbFWLf0o2oQHJf~~*(kJU$QX#0-Q0nS5b@o6?X_%R>ze2e3F)_lF|JuM} zN;|Q0y~0szjJIMZHM(Y~0Cx9*+>1~Tzo>9~xzfANz`yjZ1gP?p0c}t3Q{fqqf4Hr) zkK(PDGlo%CC7V;l@{c+Mg<>8dk3X+4d|5==&$tXbOCi(nWR!qLx@Tt9p&79>csl-m zFoK-v!7aR6Eb;$)=weoB2mhqzF1V?>bxb=^9Se|21;PV1mhkEBnM)aGACoV8W@r@i zd1d!~jj$*R2mBqW5EX@kWX5Xzm~JaG+wOK4F17sg_X2ugWMH!~?CK_uttI{=yv;fg zm>%Xy|Apo7sj#!iIQx=tf&8hlrc!ItjbiC`y6Cyt=`=!b%9x-=ZZt8|oY+~taX0g89oRU@{7+>I!hy zxn~LnE|4=Xke2M*xuI4NVM*Pc4o>|u@96q+c3*$7Ux9oe%Yhd|nRH7C@FKVHnN5gc zu_eK2AI&LZDDRE zjS=tV$Wqrlh)26C?!z)D7>x}`q63kZii8r;2mu4jBH*N}_Nn5j5giPd138i8lR{1@ z_rJ2JIxIF<08Q0fjhrZfDMT`0TR*$Pg9SV`!*s9;gDXKSCe$vRCY5#Y1-}==U~4Gm zpMnSAF{leOg7X?`_78=M0W36}0%Rmtm0(t_fZ)ZKgn>r$Kx)F_i9!d4XoSQo3>D|5 z$U_Hyp<|d*&H|@gI-N^lxuN-jgDTHyjMa(x7T5)-p(Hy620(`fB{0W%kk$x5OSr_< z;}ENnVyRpUDQIHSBZI)nq^W5>fszMGLj{xd%~0(YmVFTB(U;fn0z4DNz|muYg?j(<;OxxOOuOm+ivEk?$B`F1fls zWI#y{(NfM~=Jd8a4 z7x@kt0poA1Y-~ILT(32LFa>16-xgrVYubo?HapO*nbS2zJZx8VwmO9KWNs`Bl+&F& zvlv3sLIq$Y5}vT1qoziy*zQFx0 z$GOut<&&6+OVy|A6_ozI67@E==fWge0{FV`d$cb#fPBaX3~ktBs&u9KWVn67B4td6 z${eOvR9@`JGM;EeC7qecMLo^sE+CdBojlYY|J@T_)YUu1T9Czf#o*F#bbkg>Z{LEo zSC(S>#0aX{{VNtQNG#3iD8}(l5v|uW-Moa}K;FDYUcXwz{ETPWOqlj{_e|GiG_&vC zY?1HytlKXPsGi`ki|S(6l^sj5g*L^<9ODrb$qiq6=!_@?g1ocETh0%&fDKda!G6$j z;EJjuwcO_dt85m94Qn*^F3=y$4;LD+sa@f%_wsLYP&`>~J?bZ}M**+AyK@!|?9xGm zrvGQXLDNr<1P{?%f5&T%4)5DK=EulH9}e5<3Na)DDB#Ew%+NaN@hXVO23rIiZJKYb z_OL7%D~2c##EWA3IUNbeBh&|fl5FIf9N(>gy9=%7+ZNo>Au-2>F~)51Vwe8rM|3jc z)*P_mS}ko3^-JnT+T!^zL;yUFn$MwHCBE`CHhBhWT2ACP9;RDPkXv>-FgqJk<(^q$ z`Nv!V_glGB$BM41A3{e3w!2P~D+lvp>!1vy#ebH|)cEy&e0pA)^cK0d9DlrjDgXhv ztIwKRIfkA&zE@DQul-3;ZciB51RdSMmjiwH`rU+ijXwwfLi@eFtr`}mFAAXxZ&iYq zJKdheD@ikh4vufuI{+Sh0fX*V%7+I(W^4+8#n)R{T+|sDTTb9!EE#GCZqwk}S{1zB zB>OKcNYVQvBRt`|iB!ht{f%2sfyRg7Qps5uW9*#avf+l7I+Uuse{4~VdKB^@LoeIF zr!keX^!10!*h+SYl^0E8y?L-q+q7O%d*ZEsXqs|xc+H24*VjHZ=L`9<#Ek?0`oIHF zy|W12qVoK7%xhLHIOkXpx0K16?!z|ETo1d>fDC&E(MN4e_R^Av=lf+@JJg%dUIpc|KY(1Bd%gP%nm>nV3xQ8l4 z{v~c%S*U1(Wdv7XY?4SZomyZai;EdGRoo31=fYx~+8uU-%-@pN)!W=H2iHj=;S-6A zoNKxg-b?MRgWMaqAoc7u%i$=jv)jqP3Bb1hc>AXesX)0n{(q8COD1WP4XNiJT)-=k zlRnm&WzrzT%lWG&1e$uP0*iN+@oN&eQTFE8HS^WSyvT)sa?8eSS~Y8LRo^7p z5a@#Oy`CRVG$tt+l(GHQEGb5qUKS<^BKxJ4T)tZc|Xp@dq$goew!SKWuNosF0JJ{pm?!h(Z9xf>R$%*>B~2KVi>DCG^d*D{E%y zaMsi!T%__^8^}qylk0FpM95Py+&3rN2zN;y$XbKqS`z|T6XrF}gfRRwE@YROf%Vu(9sqDl()dSO96h8#Zh@K+Na@4# zZ>pWFDN*Avnvx+J^b7qGqmsa6v*IXyVKn5-x=)VbOA%)#tpxB(`Z7go)tD6Itdx8JvqgwgPN zXofNojsURU!K_2u9`5XOU00uZzAJCiBmjH#lk(Xc!*X^N7W|VH1y*^9x+0?3 zMEBY@QMu{iNY?T~UNL@8sm0<*pT&A`f;K5bZzMaPp}t)Jp`8ukU<@Lfoz0tr3F=_X zkHDs#BH?wu8r;il5hDF!CW6Bk%pL~GiU`^dvCr31GL(agIrgClbc&ac?~=>Nc2g2J z5kPZbK8MfGp^C_5m0qlknx4OpVUrEKB_CvktaFp?4{^fAt^BDv1j>K{(qZ+=nvS-> zU%E>xlxvPCF1}T#KN^cmO^b8*Zu-S{p|RLVL4l(PRWYuDHC4pNPZb8D?d)j|ZuUT& z8l5Fq(-{`_ep&s$@EgI9E(wIbX-^th*a38(JY*|@!+f2riK1}s=wgpNTr0>)Nfo^b z{3_G?vay_>&X{1lMq;@(zyCDTy8Jdu(+ygF+X?&;75c5G>}HOFI=C#8__5o2g_Ool z=2*^+n2Dd$b#FD|mdH|*M9o1iX*2IDl#PaOYM4H{$7#)IB~@KQ51u%%8^4a`u?SGn z(sV0w)IwP$t3&O!T1XLMx4Q@cp;$HQ1$qsCD#G{#^AM?kwYt2wdth`HHduPFR213F z{D0Vb2QJN`E?YC0VKc+FZQHhOGXrnfwr$(CZ6m{WhCAxJRinG^=rPV;ICJl{_MFcQ zv7Z&pV60vyfzX&p0_9Gc~x-BAFF;#GOdp-yGhBa zL>S^r^d3S&5!#IwCc^U(fDdoP>tzAV5)xc-iWCnKQdmjAb?i-Pvq3PXctbx-3wKyvYAJGO&RcQG?D2#*v_cSP_JdCuQ9rt) z{pI50^G5V+{Ml#!P%|+rxmt{BVzGiS_CC^LIgKOXh8@H?tO{8t1&GEY6b-YZ=8#-$ z8RDY?vLU28_zqG=O*ITeAhDDjZ|uYRsNlATN?mROtVJ`nY2f@5HN`$Bx!# zj;^6@-SH)O?{ote*D$8tJ8)Hte=C5{{=^kn)f@HG97&S8p7Ntol<92Rp747daTE#> zfOuDJwVzJHW*_GI@_2gt`SA6+M=mfJ^Rm!mJ%BG;_-#J{oIxPl61ykCe|fDP-y)be zM}W0*o>3U@7hI2)!Bv!7*NuDv24Z0d!6YUF-YoSll0SbNP!>cLR{#QQEst9?_?B&Kz-kK|+ivye~!GB1if1@^b4cjNzus_NlW5x` ztjVvSVJ9Qy$?rY7-nV1PL%66zxoXY$>C9$pf}Dtu!Fe3erNzhm>cY75Ys2uN%;ULk zwuy9Cxa3@UUp&gTCaKoZJ8TZwDkor;x&e#rG1$=vS!J)I!*@&tFt+!KsMwnAu-3*)trpqL4*H4Wi2@#c2Oy{@;h{qU!2n1! zm!l@8FosYRuKgq$F%M9UhLH7Pzs!Dv(T7F7155Gi>PaT40nD+Jeti`Xtvb_f_a4i1 zaNQ*AcP>SaZJ`LBekmQlnAwgR8;S(g3K)^1(ChO97soX3DVbA6D#8c2==qK_irGG4$0~q1ihu9j9co zMokO6T)iq?*RMiiS{dCG2b4@Bgfh`G2rwZ7+mr`D4GAE^%7A~&VY}U2Rgkl(BG98K zQ52DN7ZuCXz(Zo~;NKn+D*F79te5_x`PxJ7n)S4|gm#-;o$1c!cG2x}?tsiAPAPUb zsYSJBsQ7sLL$>SYCpOF0W?u&_H4{&r!$Gc=i2B+!GOm=n&rBY|;JQRb(;ZK;ckfB$x1Gf#%I7kpW;X)gv zlM(_DXi{$G*-2)&hDOr$mGB&=+|6j}{Oru)Mq<;IpBIh7n)^(V$<}>M5)u z5DmLHlc|qT#+_sI%u#1xm6B54=eYtY75JbEY&u6deQ6PM1Uv>Z?Ev#BLmA>#4hszh zikGK_3M!l*>){y-U(v=Cm8;bOUR{k?6rS~j%qH84iK;pE?1E)pU#&${;M6}}F+q$H zMsnK&w@(o%WC2OU@KVPg>j2@uicQz#14|=zxD6L=8-)N~#@1D$vO(N3!x{LceF9(t z?SnqSmu2*3H*jYsReLAAE0*+$!QzcB9qZGSjwrv+> z2ou{BU%!~C(g8KQV1{sUD8HLN!ByH5NUr^=uHit})P`gQ)`Y!svZY#$Lhy&B{>?OX zYa|lI;XF5}G*)|xef2t#cC|L@YCROL+NXuG|MrsBW+2^k3V_T`S{GD14_eB3xdz)i zjpUSU{KrwsXLf46-P6|f<_60Pa-Eh>PX_x&qSX1TIy_PqKHW3!)@LA@EBiM8GtoQY zHWLN2cgc34w{`gLO5)w0*AGoUDmrVK7{AnuZR#l1>yY_O4|lE`(yIdko4W2g(Dhf1hG}6Nnpcvt8Fh;&W1a4aaaICZE2R1e&jbi z*AoBzv0Z?ckeE<^k39hTI$|^-nN6`ny2;jvqj(><3czXls87`R%{}++0r9rMMw1?V z{7sQZ-MQtZj1kH~{TYV6D$J_ej4G z<2*|^a}~jFGZZU<{6(ml5p&m2@`jCRS=b)!~OvMAn?iag$X=?iZhJ_o%#4AhbEvb^EGU-_Z>f@b$QT1!7vwMMlDJZdbmVi5~0q)H`H@dzSD|zKTjR0H%x>5=90jtip_eZClw! zxr1fE3XASp%W5Zkj2`;+M%vDH8T9t;DV|%&e2!!3A2gBX>g(r{_2lVn;-`_`4t3c= zYI>#RjrA}E1!giChet5X3h+W+LfJmS?Pr37-8j^iW=`#0>x3p=y-aK-~jkf1R{ zjn)^_6VwV<0KneOcQ?h1+eTwaT*VUd{QdrB&40%Ke3# z?tMm@qE+u!U8iK8(pOM-XZs~^@{cOp&(t*b$gr>{@~F$qfIZ#k`+K~-bx^(flg_iw=w!pRt%^wxO?4G&-wKUy5N{IX#>JK$#hG1l6m%h>08k?ZQ32xKwFN zTlBKCR8rnmT*1^fiHbt+DYxvQ-rB)dRuTExz6-b2-1uZndZMoI#|DWi9H@~~`X?78 zuA)TBWQV}@i*kl1JVBiDq<+e{ZW zDYnaNs?*zy;?KsK7kXZDq1w2tY_oF;biTt5xW3E3yy4BesAy~Y5TNfTbfcr>#}0(P z3qoK7MzB%EXDE#Gu3e!)HG8oubUoY=%vOEsX;{vH+3!2gzia}~U38yyI4Qp-Tj1!t zG&5S8O$L9aoc|f(s1zB~_I9`&o3js0Q26xHZgC_&B;jD03zse2x%&A}3ACmJ|2g9T z8Y?p1PsKdLgYPiCEds7(9S+g8`v}qH1fDom9rV+SrG`1`dVbl94d1{F>|$&^Vkoa& z3_w_9A!m@EtO`v)p`9&(<5MrvCwCMI@|WScYb0lWV?5f(W1FsMDHGjaMrE+w8i04A z<0$p(r$%l)&|t2wvY4-6qg?2z&~d^5C`QgGu=n~~`cwKxI262DMWyacfFG8Z7Pg_; zs`7k?k&nj3JCRDao7KG=&f+FUp}!SEc%C%&44xI9NJG@z2}|yiiikQPm3C!29Jg&Z zopurSSOnmKRuXB0E9N^3NkO88cji>DC+zgg#k(`jQ{ISiep5BSqW|qTUe5Ig@caa( z;5hzW!QsrNfS~3PV}m?S2MC-x#&q|%UX8kC7g0C*y!&PsJ3wBdgPW7^n!QB^m_r1e zEKLLPA3Q9>k!x}ce^mq7yn(s-cy-Dxs(NW4=aM5@e30JR80jHi1YT|w!-v)#DakoQ z_{?RqXk;Ld$lK8pw&S#{q~YfQ8b5|9croT1$3Xt#kVCN&`hWDY+8& z;2m2m$`GL6_gihsqfigrtNslz5R%Vb>GR2O(3epRB2{E%WJVg;ouYPm6yXr(#@1yQ_qn#zFgsWk549%NH~!IN>lf&vqC+`2Whne z%_;sDHm6sZvA>~kD(c9MyF{4}>bX)XH(BvJpz2a(#%(Ct{q5qFZTMicF@b<__DctJ ztG(_<#IW<8bW#hEXtfd7&U#vr!VrovtcdYyuC22&VZKkW0pFLDh@Io9&;f+F3&cP$GE%6Y% zCMq`=O&fPE-Ik06@fvI~#{;W?jdbK4yJUb*Ye;wM*QD>Lz_B!TQ;V@ta+|b17mlIu z!TS3^n(uB39Mve(ZEui;OKnTV1|Aj6^S{%)Uao)Q->z(cAT%nt=qBY2I{S~*n=1u~ zqRzNFthH}q^d>U*ju$uzx1cm}`Ha%Zhu>OJ#)V!eW^K-wG5Nm>zblhUc#2qdf|E+@ zRE8P&M@q%1HDxdNiws2CmBjBrmq?7tU4IHH-r~gA%?d92_M{; zWDi%~e3`fdWIDc!S7=&k`}GgQJSRs@9Ka^kZ>TSR{bZAXhF5X&{_&gmv9W{*&}I%e z<53gyu#9v+M$}k;=`lQtdVc+%4rGXjFECBCVH($2C9q@E2VHKOL->XWa zRJ#&o&IEHQsS;0v9;xr6TF~Zx+xBvNj?b>X+YOIQZ)!mS&o03jPnfo6=hyjsI6jZ12BvnD z_h6(_r8%xoRsXr4jCA9U0d6^97KS>R3#sHqp?IWkPAYS2+L{yOtKpW1w2(q*B!%eF zv+fAUtobE=XB=&J-ROxMF+s7R7ta~~I+1m?a$W70bC?kVBr(+>vp<6(aKc5D1Oh1*b5_;7g=$TYCai?SWGXxwvi#Eh`*20q4!)+zfPcaR zC5xMM7tC17OC;qk%T4-aKGzX%e$s!m?E>|v1V{A@k``QOsp?6 z8N;0Zv1ZSQ_e{qRN2W;!_Y~jTHn-TID|2+gPM!8RmMI-ezyUY0vhmhft`uxckNmbG zrxzO)i(W}SdpgI#HO`msLd@=OMHkt+mFu;db~CmSYWC7V+YxESg0~n9x_~o2XDbXu z81O^GTSx(fywE^xg4LeuM?UUU-tMlvP#s~`p)zD?mBK;DWhG!w6Yil>B!rdB8snAt zwlX=*oy0jK18UES1Cn&^$0BWx393qGxD+a$vg@J;B5G;a5R$q)DUy3ENz`{4x2W#0jiU@e~IEciYW$ikLKZ?XXdk=v(@hc z4Rm*9BsgYQ_`3J6HVno>M+`WDbFTqBN)K|k7od5ZQ4Rgu&k-9k zWhg++cl8l5Q@JQMEVTa6q)uam#*y;;Drf2~Ab&0EELcK1_mmc5jUuKVW}pSoe&ZTB zR;X7*@?bOj_D57bXL;$=MLxRfX7j*}c)#qAED;zgP>d=f=5Xwl7*O`H^C!>&2rYw| ziQR!;n6xnNkt{A_B!E8eL4f8IahzSHr~Yt>jdMZM2Z%>p>7PB*>P-%@+x~C@SJPBZ zy`wd_=4RFfZZqf?d!>oIJV_ri(NGL67k6vjA7=JN@ZS@sifp{B8H(z2CZC}Fi@YMC z+QXWV;a=3BDOx7L#pcW9ODVU1P1-;R#?h3r4rom*dEyG@!2p?U>p^2OZ^NA>E7V)5 zU^Edz>=%DTtBuauT#{Y=#&0YGQL>qhQFv}Rv-$ks2jf9((q3=7pTP0r6;gPB+EO?K zT>KLG*6k#K;hqXb#hNfBx<_FH_fc@^;1?jnH|8+AxJu^@6e>35F%5qkjMUhN!H42C zx+#D@u(&1y%m8^|$59<(I4_7}i0o-*q~)*kV5TrI16(f)b3|_{w^2I01W@E%G?lTL zB5N8SpT;oup|K*p;}$d`@Qg!Q2a3IbcHTHyB_VE1-@tBvS9RdGp{ zv?z4c%4z*GRK$l0AvIu$v`P;mlRl)=(iLiF_uVw8j{4MXY2~ZqMyMZyDob7;7nQ$J zXnR!9c6nS`Dk5n>3sx-M6mnll0kF31WaFvZ)&s5u*(9c!CMsBqSIc&PHpNxG3TV3a zk>3JRWnA#2&7jJS0}J8zyGGr>#XjKm_8E{cR2b!jc9&sttJ%rvG?25GE=;+|b45Xr z(dGK3#+_%^Q=y=cw$DK;ab}JajE&aU8S`PuxJGVEk7ttYiXcb;nz}9_%|`NZKj*k; z4nS-&R9k~X=dhiZz#Pc1kyOCi`rIOCN)n4&;~jmtg*HWz?fPCIo^p0!yR?1YoJLQ= zV&>;q)e=@Yeq$4DHY1yE|8>OE^;(v+_S)`w&X$02xnqD4%f)f>Ym)#=iwrdAcpb?8 z!>vCj-H)-sZA-g%4BkMKyYlgBL-#Ps1)%@CdMEdaB!c6T_R^_jXk`Ypc{{)JwBF3+ zWMb|x5WE3QJkn(5&fRvtRyB*sR5F35fG=l`ZsV1%vzI9bgzR9?I=MbgchNRrt<)9jOqrjC&AO4l8t|?Ph&dFyzteN$E?q32aXs~Sh`d{JN3_d?4Q8Z z&8fG583*|L)ScpH97(%JZX&aTcPL@R4qz#GT{3wcVq5sn;kvahx>M+`WK0oEEeS%bDF1PqQJ1_ zeH8Kc#FOX10f)!^(`zx&TU72Y!F}I0fzX9(I&PV0I0p3V4hK*s-S)4*_T$8)MONJ9 z`+s7q{&RICcJ%e_0S>5#74}yYUE}q^`W+kwZ(`@6Lo9e4jx@s^-3l4iVt{`7t?_90 zX}1~Q8A@fQ4Cb-!4N!5~?^&nEqc}G6vs)$xbW7LUGU+VcyV624s-u!bLVG-&^U(7O z-#&Nc#nj$vA@DDcNBzo4fK{H5B-xOHw1hJf`KS8vi(kz{K-Nh)gHbuob)ZOF(?u_E z0qorWUfulq&+dllhnxJ9q-6e|B&GCE+6VE!(mrZb#`zwgQ&E4ywoNuHnQhNAGeK#E zpsXWQBqt&k&j2?8(o!U{)C>9K2lX14zV9R!x0HGPo$HyK>o4}fa74(KHG!M11|9}Q zq)f>Dw#Zw-nI^g&9F9lc{n2pt5zBUm_gpoLM7;ye2z1VlM-Btw*#JP-r|0wG)#c6a zKxvD?u+MRns0if>ck=OtQ9!53kktJArzDzfxJax-{MZ^E zTqb={{{8{P$FbdvN*f?FJVvN>eMP=4r-(Y%N$2_aD@3+yyX3W0ISRfMLl39zPd{dO zk`Pi{u>z6ILzCPg&F49?jz+3;`GC=(Ia8EleK#Wc@Tb0=Du6werOIJ=@{z%u#l=~0 zkQ_{4oG%MK3f~n{M^>N+YPE#eBdRf5_=)G+HY+8^$5?lc#0U^X#jH|3NLJmi3>@^2 z?}9^N1?X=tgx^OILT%oM-*8qiBt+FP+Cqu-2VcpZwO{HTLw_*o!so*c>dZyK<0h4N z+5ia=3vwxgqDWw(dzyzFR**=H4{x^!&SSgRzpzZ{BA+2mi0Mjog!i^A7!=+}ZlcilZa(6f zz^E3BFpQ}Yu>b59V3V7i&@8<&Z*pr8Lng6RlE$TgAgR* zwcnO2IF=OR^{F@gBPcx01XE#+w1a8E;W#7x5M>0XhP^vo!@zn`hwoJyyeb?q4=D{U zPc>7W%Y}f$gEEancU6ISS?5(et*1KAUuNXT4*2ic~IAVVd45#f-2$|CvF^FSCee*u+#1 zC}G&f-2+zz15j6c6mw~=;&Kup{Wy&(f4M$Bd79<$DW@?q+4V1_)Vm71vqif)D(~*f z?S25T8}%*a3x7!*h6)&+5^N!2fq1r)7)O4gb0Pva@#~u2{hjWwG>?43ok-h7Ff){{ zXi}9-=?2A3uaBh>9la*OwBt=(pWs7W)Q7J#F~%lKIL1FW+{wDUO$qX*Np&SK7n%n` zh>1|RoTLen(zg#I0;daLShX(M9nQd}OaXvhpm&f0;$T|xq>M?lmO{krI8czJjYulB z40*I5wWfS79as1PQwc}IT(jRX4F#5%24J-10qD2|tFL++%EBVUk~*UjeIe$iH<#0$ z)Hpha0wJq6j=&EAyX_H?mkLL?pK0rPANt=m6>i%uH&Y|WIDLVH4h^VJb&|TrvAo;|I z_CF=K2h{A-BmQrF{g1pd|1>N7$SddnE3f}W#<@^;2$I5_4cy<~kV>|ptc|{^qPfA# z!eNM_u_B$j4?FmHyE6O*7Upqfa}a2mQSyF~W8VQ`c(~Iyk_ol43LpckStAG$hl@2B zO1Bo-9KSNR8Oj6L8=!*K)Yn$GgdDy(Y-6q_@{|2wddIDgv4Np=&aozw0sCNJuUVLO z0!aN^8Y3gso?mWnj-2`$xv4kS&Ibg?Z7Lg^n4CF=${`>^Nl*7zMtrF)iLVW@Ge>y$ zX%9Ls*$zwlVMwzMP{J|L?u=g3=nrSGx9dv}(~*_y)1mDN=ISTx7!Q-hXa>$y-?Y2B zx)m&Ki{l$)c$J?U$oab-0CYpeBcfmWIGK%gu*r`bL|aq$wi*@h@|cU!3Qlwb8h@pB z%p8|b)zj5{DmCS!ApHiyI$*z;Q!zPtIF#siaL^#I*&YmWLBMkf z7u-KCfkvvQ8QJ*l2AoV4X`Izu;TAQZxYMVF+iMd2-|6GHEzU1H0QC@0zlu=fKuE2M z0GjY@iB8qfPKjjt$wdQxd9Vu{jTG!J!+AwOAgu&@IYckReZazx!yb(AK$;K)t_ps< z<1nZUB?@x14l06a-gSCOV-uV-amf!psx$dcjw)ayh8KQ{hrD^mgKB>ziwNikl!8?0 zlMFi-eqS7NLChq>0i-jrbkw!lB3PuMR@DDYbSs}x1vk9=g!mLBy-1grZ|6@_?@de7O5HX;X8yStw}!1>F>UAO^8oD(8%=OgA<+c-JMwsyZ7j4^r|FH*vBrjosT{RSOh(fg=oMQg z>{vgS2o1^d11vI4l5E`#)3-=7i8L{cgiF>b_=ezMTj&77lBg0pZ^RF3T#WED8 zU=^kk>lsMAR`=6MFDU&r_5%s(^cyoSTrY75GO3!~0W{Vj4xhDMtT<3-PW~F2FJK{r%Nkxd2J88IUjX_2l>_v*q=x;2(_hdv=h+w{ zH5bxB$=RS6$%ltzhv9E8e=~#Xf20}F<$s7M|Iuca|HKbLnEpdRrUGb6JO8&fi>R)c z;7wiBg%0i5s9ITDud2y8!iz-NSRq*;ITZkUd11%=;$UMEwu`)x2FuRQzB=AB@%nbM zL%Vm$?2i-G?bGjB76PE{dmc%iO!5@+(%ECX5Wc9ij>)2A__7ttKPqkNb<>+5BRQn$ zx3-!kW!f08LjXjqpBw=8S69AQb0GtyOQcd30c2_W`V8-XVcn3&yPlYg)m^j2OA|0b z0oDiGGG7^c69QW-DsdtCS_E)!B>j-gXHm^58_R-8Y$BAx8yQLyTShU|zgOb+C8Sj+ zX-b0LUko!c{*IvXVu6O3^kGv;p1IgwRkre2NX&8wCIBGq#UK~5IzwyvSKtgr>hXg` zPsMT*Z0_8}RVOcggQJNAP=&Kp8YP(+x+ES2pE>7PlaS&c`tX@9ut!#PsZnWvDa4?f zHvbci?E$iE7UzNcnL|93Kkmg-GVowT{mPUA`$=R7WtSCM*x|$VOeXi4X4UMHwCSxC zog*1#jRBc!vk`soj~1{bL%DF{0-Vsyyg1Czs!li!wtqmHVA$mv2jJXFu!bsKjc9&z zT=(DF`-9DS29{Wnc8FmgAHWBhe!h%-a^yv=Xl~S8>p@cXi&WHb~3+Sgg-?2LNW(U>Ds z1aowAgLM`cG!12m7>Wf681%vT`|^X}#xGxvSMeR7Qb73`YHJb9|0~z=6A$9k7aYSc zBmi`!H{dR+3pAg)h|!XRi>gEGw+gN^vMxU9+oPm`f2VA%b!-G)!h8HSv{nz;s2 zj7-GVyn+B)pE$o4rRFqzD3~kyWxLYNHq6$_YqXJ@b-NhwqPRn=eYtY167IBC^W3T0 zp<8Xsd->cC|G=}=+)Z`yh_9KiU2XZmR1wuLI}fhtfl{r{4XilT zlzYBk8t*wm$hy2b5Y}eSybQ0eKdX=F7Yu3acPV8oNN9@11>Hr?dfL0K)~d?wzy!vC z8>i?AsZMcZPTnvL>33xc*`USZ&7l_IhS-leDF&vU)s1oQ&bv}ZyS!`==6zQWg#?II zVX2w1GZHx99Js^=yf*YqErj;8+JTk(MRSHP>nw^25=rLp0Im$R`qX}zzw#y8C?Ya- z6)IxgYYiE8v#v}I0u(CWqnpQK5YJI;=3YRod2kiN>sAgo z(@Kqm!J!#`3xm0>uD559t6!hDWCMhcs06a=l+SWQ(T`_!C#vheOx}zdZUn9CpFWe` zJ7v4djQ<(vqX&<#xJU*nk&G&bSQQ-)Y6=7)M=zR=D7;=MG)-ItHNL3o(_&Jq?ii8L z)91xyC>CB5qDdZr@ckXti zfI*509}I*9XLPMuozZ63wx^<8X}C`b62JDWw_;9bFOZD*7^>182dG47Wk3nWzg)j9 zAEaIkmx6~RdP8vQFv20ev^P$m+wZ>4V6EtL@)bD#^`2KrM+rjmE}6lP+{NfgUci@{ z4DfH_FrXk?+FujrI}+Q#7E0sm*?hSq8VZ!nOXCwksg3w(B+6kRBZT(eLfZZ}#V)cR z7e*A}C1y}avWtp(2Ke4#di0srQDfB@pR!*xdO`|GvPxkmxL;p~X)X(?3xeC`(qwfO z62(Ch`=tcTYuK~Ek!3M;YH*mq6oC29Gn_MmlJULPWKj*z%uX+s%{}*ac5acfo3q)I z;^=Yd=ZR2~@Auj|jQ30927RSi4P0!qMbMF2+U)&~@wISv6+pxaozE+%oyhh|6B5)N zKR&Kv40u${;or=`@}#8!eY;X{AT2|LO_2_IbQMB55IO;lsH45Vysc6{I<3ZMTr%GC zHU#r@glnc89CAWFB#8iH(Dzt{j~yYVB6m|iTa=azrV+{YWja|q>ar$&cVVDL6bFKN zfjcH@9A{Uo9^fi;I}B8ivjlg392R4aVt`w22MtPi#gGSj8`Mo7Ikyl9lb%tG(bz1N zVsZ&xjSthH|KwO%CD|j*5Dz@e_LCPFleZ#>=^@o;9pFWM;=NG%uAJBGvYOm+d=y+XKN_kH9O6=#70!bN#$$22@O#_l;$jU>}>w5rG7A@Y$xh<^L&~%<`hy z@Md?L_|Z2Dh{=6~@cqiYMY$Q3&y=fFS$cv!RtPCz!11`YR!~Ely(L5K+s6#*zVk_# zkQRtp1WXd8GW#M>4rJkgY(g?xymBj3WA8@tq@G zSlYdLe}H3j?Mk>J>FXZn9EH^X!8ig+GCna;2-r$~QkoC&P4f>gbgWjgaJbcY3KAHb zS4X~`Y{o!Q-ztgKpeYCg`xu815JjPql^@p;Mk4Hq?h>zLH${!WGqDUZ3YadzC`fs7 z_Ie>TpljQ!=<~l&w7BkB6!m$*C1eao%8@mHdg=M1P+s@ThSwWIjkJ6*-B&fY2o*~t z1Aw4nfnutFYaehuu0v>{cyE*Z`c! zTF3#=xw+=J*0HSZamjNzl1H7cpkwlEH^5YYc$Mxalv}K_!Iu`S#H&!@kF*`7E(Xl} z3gT0%OGm{~P2&{oY!wbiRbD)X9sl?FB9EI@HD#{Q$k<_uiUpd>tHOu!jkdMtcX$;# z^n1v>WEDzbqQ*-kXyqwON9szo(a!{`Dyp5a-+c=y5|EHM)XgX^0g|y57gS)fayu^ zo&t(bS&mC0sIRi#HtuJ~z5;EgqsBBR(wBUY1wpI4bupo^J0HjPzYw;a zVv#Jtt8Ky~PA0eG+F2{n++oAm1#6<>R2yz;d$RfN^=sKZt7EYZ-r$%)OTc=?jJpl88$OR(1R%b-C2S_t zmHns?POQ$a|5tMR`?<)dii&Sc)!5wCi#ttlv;2N#CW9oA+@~z2^8Im?3Y}o=y!1=0 z`CS^TPQkaYB}=Fmcn=BrAZJqP*gCxy8KqthNWI@nx1A3ux1NYMuMa82= zB8CLy7vq9-w9Vp`V>So1*t8~%kVPf7s@^D*ejM83ktE^GeAQ5z@jfyWm&eAsrf%)1 zg+~!66`p|JujtS`0!NW|aL?w-Tw+oVLnbYm3LaG5FX2XXrn1G%7i-$UB8zSwE245O z84g|L-#jF$$!NPLwl6rHT8LN;M=BRqv;%v)nv31ru9^=}K`zd%DNGjd>Easo1oKcD zi0G`)%hm%?>DD!9^Yt3K%2Gy@SK4jjFwm63Dh2@Vy}ymP8tWT(Y-h;aQWe#>O}g7A z*GFB>s}r=di*_T^B9yhi83b7w3V#r^P@hh@uC3@R?seJng2s|bc`&Ff_hZn_OTx;~ z1#KEp#76-RHOCxop(RcRMQ+?)%D5As86o}i`Kv7BcTOe(>u(Dj;fX>KcI@2mM8m*(zk{1qmS7S9Y+c^78c3$sl1mqm6v`(DcP$5uU2 zcUNVs-Yy+@8>-M&QAaV_`$y@p`Mfk z-`evUNF_rD7FGI0q~B2%Jo|SE7BZ>IKAc$cW0@8-=!xtJ9V4ok>EMO|vY%u&o?cEf zSDJkmknP#X7$#UpJ(|wACblr>-YG3HKrI-`h5Z8)Rnl|GTMV&6!aY^Q&1;zbMSTE5 zzxttDt&d=olvlJgZ2Sx{M69!=7(gFKE(-x2qTWR@8wL(4qBqt#z(^+Nf#5bI!VA*9 zz1b~x3y53J=e5rR$%BrIBdsNHBbYkwt{HkTZ>P{b6!T&^T;VJnhxRL~yfmQ-@VBx^khC1H0|G!RsELEI_xaQ^zNvb4#zLmZH!)?d-C9#a?J$>e8$#U$fwwb=ZCMP_VUn1KPPJbu~#>KfIF z^>8q41IyS>j=%~uS5RykYnZXZ*xQM%Snz7x=*K+cWFG~}^g`ec)u)h^mC`>$lweMx zss1#LV=77n?#8*ajKT@CB^l=>wV|O2s&10w^_uR;Kfe>rw&V>6K}CX8(FrCS?$6f< zLM=<4=vgpzj+k(0bEgB;-DWCkH#dZ!jE4dTJ7A~%FvkLjsi?Ky7bz!@f#+T zTB!^~xy?@{!^qp(8BBN(D}QA`7ZoLmi)2F=p5C8V>Uh>l|t8^~beB`_%z$ zfMBfA751JuT)|<|o;V!6bm(Z5tVPYKA>$oh4#da~*%M1*)YpuP-9)wys+m+)CFF_7 zI8b>8(3$Ok!B)Twp1s{=@N1Qr6wxWH>f<`yq2WMM@XGSwV_&!DV_cIP7yS!RQ+AUS zFew?9399UqM=ongr)u#j8~7jd#o8c5e>!+4Y>y~VGi!w`B#pp>ss55`jt?F5y+PI? zf#;_;Eum;#AvlGaenX7sYNXOS-?6k?BqHqtB>I}l_ z&_eRtbq{C&R6SH}x~hLCtl}L1nmOQMmCa_BaQ4d}faLk7jvZ{?K#nbUI?_8D1G_fx zxe^SFWi2J-1&C&XUCJ8i$muylAeO&@H&|0)u`PgL02bM}6LSl4sB zR@@M>1|Hck)lrL64sKmC-+EHOqRdtVf?|Yz4XuiHYq;a!fJCJCf zU1qIuKvCB_PF7p2bK-wk?t21|{5yEn&P6wuuK)bFXFtH=lX53N^#0MkXhrg%DH?km z1E~Ee29^#0$sXU=M3`Viz^wnB)B9;bDP%+J{%KZVQ8ljSi}T~1kujsv9w$rx*V33g zK(ML8z=51Yds8bP2=*(A_gRH3RE17VL84sNCdcl%CiW-_Fc0&|%eXy?P4|$l zef#QNiU&?`5+~o!rgGQgU52u@)qcgt1F@(P5~Py7oP1RDOGy?FvjoI5jU_RManvl~ zRL&?Yeg)AW>3A|A|7|rJ02O6@sAMTH-bLR)^o0@@Vf7IEzd2Y-aBtJAIz0ii^ zOm&NN)O3h8Rf?mI6e&2A<%&LoSsEssV?HEKSZMZ{NaH?1>YZ`1b8rmBZ^nl`!`_+l zUX63T;fj$KWC>xuI=Gl>)vZ!26BSKDMQmNoFnhIewAd|oNWqK`(9@YHRcyh&CbeJ} z3h;NyS$%0cq76W56wVx@BZfQ*TdccNT^@>Q=uE-x?)DDwW*dp7``ahodnAT?0l=+_3&WX`*pgL4LnIKZ^!I1X1H5{R@~s1e`Nk{nf1Agz z5L*p$KnID#RebWNpt;nqLiaTHo)z z6@^FNQ+y2@tkrVQfW?6PLK zp={DqP)ys#liS*|k&h$~d(sg^?sltSdd{0U*~AXI`}Sjv@do_`hU+IG zI$Xeva4LFc`^Vz9vZU>u-<`7Lp*BfqyU0b0K($=$BH?xk79-?h}?KD!R9Oq=IDQKgd09<;W|&gGlZ14OhC5Nij^ zg>BfBSCX?Q8B(bsX*w{LwaQSZbP3#xR9*4Bk` zfm2&Y-W6`Cpu`G(>z)Q$4NIzqDuY~qs1EkOH@1XTbUs?2?{cpV1`5LvVbFEdCjT4t8Qadp=EP1Wwr$(C?s#I`ww+9D z+qP|I^Zz}&RlBwCyI*uw*SGsR*Eyf#pU|_yuAhK}%P2(woF1ymqX4xSbU+ynjV;J# z?@(wg7@SLv1ZGVPMg%K>Bo>ScMysxP2KFWo{{#lRWDbH+IS5vYkM+g?Ru7IXs*er@ zl9!Hz7m*6|NyZ#>z=7gsm>gy)2NProVqFH(8(9v4(UI*yj@-}=&{vvg;&;Hde|o!F zU;x$qxBE4xfU+8Ul#F&!h6+#KL&xVn`2{5~Ro|2vH;V=CLkcCDu>o2P=Sg=Y@v2S|{c6P>JVjSSXr&a=u%f4^L7D6cNoQtZeHUkZUfqN2^ z`g3v5DL+LjIk@cqNL73eVv)ZCy{_K)zCOkUm}M8$Zkzxfw^y6vSG)Zg_Gk%W(ku?F zFQExh`j8ceLzkCrUqE7Hd*hf0@xhQfn>|rrCEA;Wy87cZSZvcd+rSsyc!)cM0aTX| z+>g^s6$$-=LwIdps|ldX-Rj;Ot<#bnFV4+9h{JXmI^S3@zmqeZV)<6jf6zw`UG3^Q zv=<5;-VcEFy~oqrf<-YmV@_&;OYK*(W=`FG9eH#4n|7)(7p2(obRYjGEpi&81pmKX z#Iaf&t!rAbjrIxwHFcfzD7i5lgH=APcOxSX%REevdzizUi)yU4ujO|?<{VnCaWxWL z@1#IPVwp_ITc}%dgi{~`^bC&VGo@LLu3uip2dw~whseD%h~dp2xzYHHh9;urR;9aJ zySjE^Rz5~1Wi+|}S_j~MYstLv?b-fOa!ydSRD*eLaC%e!{qyef@#gOiC35ysafnWr zUWhl~dpU$>uQ<|@I6>>b2g)GoeBYl9j`ia3W$q8oFW!j-je|0eV)ALsGyD}Z${g$< z6a^GT!S8z;Wm~dKzf>ayaX-Z`KVGdgM@4P0i zk81!=E3CKjXA64iIhTm*l!c)_xSzmWYXDA$8NHnTxn2v>=WC%Mx1ozvqa(I82Fq}y zsC`K?uB!ZDfa7}8{v$r3C5NYU2aTO#`NRfk=z1ej<*kign1}!P?&Z~w@cAV#@YetJ zd@Of){kJ7!a`jct=ljU{{%J3XPowjCc{pR=?el#ZP=h%vzu%i8>7+&0;E59^c?0M_ z$cQE0;VnC0UR*zgLg({-*_r0G*{V+VZSr+OY+~`miC{2%4IqMWDvucz#l6L{wyj#e z+xuLl0QfqFe;W@UD%M@?g{$; zJad6I&#yQ(y5!3vC(P(xc8h%m62Ov$5_5^6PZ3>I{nBTI^2RUN%fNoT2<1$6jA(}? zVpF|{Mu*TV`KGY_LT-vrs_4k5B5(FZ!Ip~Ptu{?cz_>yn)+O5-s{ldokE9E1t=AXi zvolnxP@E7lHDShu&|H{1TzzC5PI6Lu`Dkd8lR+tU+DM}!<3L1|(Cm<@0I+py5?0a{ z9@-SSqoT_NlX!1TjIEH=;*6hhc~D`9v)aY~8zhjFbw7cq88xA);-~G5 znVI!}YqEqL9xy-w$NyVr(XO6W zwhDp4-<8}xs_=lY>X&B(XEkKq6=7kK6<+OFLZx-);bql{;*IU6io0_ngQP*eDMB% zdBfQtN+8(bX{^~mf5MmCOXYE6qP!+7Ny|m!7qiMVY9N8HDi>LUDM?df?g&spBG62+ z0iZsWIk(9%SPNRBAGMuDiO-P_Ja9?_U4kOuFtM037kG1gqotw zAT9>D2vt>?=rB~jy<@k!(w`e(lTE^x0HcGOg@ZvcG9GsOolMQ8P%Sov5Y!!36A|94 zJ>Y8{Jm)K0mFK$?Lc*c$RSOEoGFerg1WdJQ?~(VOWU_dQd%ibIW)Yih;4v@2=0x^L z)l%*?LbN$<{j;6h8lfBOM%^X9L9aOG<6;j@bpFg4$FcTiE~f!sd5Xc=dH%sP7S+J2MUOt9sb7 zPq##mnCRGpCwC?gdv{F71RP$Z08#s^ep@}YDB6BnHzEZPP!pDJqN9~e9qtHX%(06gpP^ zt+5oDQx6Kqac(YL>ql0RU-2Iz+KK>k>G^}R)Eec?_3PiOlw`;7mPr2 z>9{R;-z$8hY-s7@X&b!v0b2c3imBNy*Ix=&PYb`IOYgF#YW=9=lE~|thMFUNZf@ri zMeb_O>)BS!3@*wMt9LdPJ$)v(?6T4u(7wm2}~$jb}Q9gMO`t)uvz$c;JDbiy>op-@?=Rs{qH~p zX8bRNz`*jK@!;n~1qX1z{nSVPG>#0==6GsnG;Ti4tjhRUdFGN0Eh!_a8 z6;g)%J9TEm)00jG6W9U02}_1vBMjL3ty_apvvmhG$bq2lr@9b zuu3y`u34eH{1qP@=cYjRE|?;kR!Kd*u~9VDWZC%MXMX_D@ByfIX#DQ_O_}*q^P0y> zZ7(jEh!!!e2PJ9n1xlPcjNES11Vb7CHH7P<`O!d_l>(+@AFYpJUx6pD+~3zZI^O0^ z8D&2J21C^w^p`F>CTUjY+yF38(V__FiVWtkQyTOA*%T$^IjWjeG{t9O)D25-wec}r zzJT#J)DwfEB^5wjuyNNlIu?~d`#d;RGQj=f|6s4U_-pxBNMrA^i;6aKpW~%#T2(r( z5>0~(XY5vsPqO#mSG?H9d&OPagKg7i$8Fie509qio|1<9*v6C46bHA6BY6&7ZFNWZ z;;{V5;=tzOHr{oiZbG!O50E?%eSW>gNVQfwyca>=}RIjJ3VKBZz(*Vc4X(Vj6Di4$Sna5quNR<`hFGFx08$cV*kIwjad71<@(i~F?ldc}0hg&!ZrYKqL9S>UvX z>`fi;+XBsqYR@5i!FHL#_fRaBEJaBxwR+)ge;viHz8OKk>o+IXJ0SpR*cgodM?dDs z2-(;Eyc`ok|0UU!*2ESD9vU#59h%S>Kk!UULL@k8fH!okoNIFXM3D~apmX*LoM zyMu|eHw(*N-mdx=dq1ux{!XD?dzl%7qwK2v5VD@6@|_O*c;LjjvU&Y&j+;dz-;v$H zh+E>&>rVjWj1ioi;;j-Pxm(tqG*X^O!(IDc>!&lN=Dttw>h*btWLLn5ht(YnKJD>w z&E-#HA6~jD{Ui$Wu`-$=`6}p%+?uI+trQ)0@{Kpnu5;OBSMy8C{o~r)Zl!NZMZYZH zQl&i!;WL$f=Jh+cqw!J6hXk}Xeh^m6Jb+^6`6;Zy%TH8DpAUsVpkSAgg*rQ5;qBZ4 zjSK8SM696Kfn|+1*iB_iciR`Vp4GVa0}~{ zY0)IU&Fx#9Uz_nCY~*d3-Zw}%1CGqkaq&M*)NWTcAv`;g5;@-~j5_@)LTSCg@fRZ5 zUIXx#hQHlKmGAu8G?(s%&rZ)bP)xRpz<;-~|JOFb%EX-DuTBL}Uw8aTI{7TC-BcMH z_O&7ro|Z8ujHHmyuawcWAj;yKBiC!(=f@`|HO~KJoq)*V4YfJT%xL{)4C}m}E)1!x zH#Jtca`c(MIEfexBh-1DyaSNU`qIr3GUQgm4L-Ai6|i8eHpNYnDL}B4&X-5&6WAL@ zcd=nBk%9wYteOF}9kIE7s8T^_$P-l>)|)HyIl6$RN4o*PVeQNqlZ0YKn6SOWntdbe5n7btT2vh*nL>J2w8Bg|Bc*D-br>AiH zF7qeyHTkxS2S4)W?oE_c>lf}t49H_F18FM?M;<|ha+1(@N~FBem@N6}Oq5%Wo9Y|h zlNkA@9!VEK^Tamz^8J1DQ{CYYep4|J@8F6mGrSlFsFQiuHMqNUfikKO{`g4>c!b|P zbE>x69XJ6)Pk&j;F%bq~xbU(mV;+smfZi0h*?If#N%)~?;Pp2fAPqo;sIbm(qyTO_ z))bGO5C>dxyyt1W5agPKF|dCfy>#I7!9;hWkYN-^brH}Qg!Q5W>sVudegN@dRBTxU zOxMPi5hyi#84n4y6DbdPFsKg#`1?7vJJx{x9S#7mgbS94WuIgTCWa%9;E~~~+t|HC zLfUzi2I&-})?tF*1o@dGMH5D8)2JFzmbircU_fXOZ8vd>TkGrbwWvF4NV}lS!6Rp@ zF`mm?vwjU%=bj$U?yb5tc)d1_hsXg~2|ZmnSccta^gFx)U8Zk?)br(0qwC zir4_%$%LtS-DZMpV4`-Hg`oU%ISl&T>cM(p2B|xd-dMU`qz74~ylkg!E04h#Vv!oahaN3+N;29V{%iUxhl8?h*)?N|M=qAJ^lBd22W}x; zZHW$A4eU+EKX%(vS=$7bvdL;g1KWuFDtW-RqCG@u8@?FJ#WwNpF$80(<_2QjB1e{} zkO8Oex0dB6k6$WDVYHW+rTo?~3+#0Q?+q2{A(T)7GAxY4qNU?V2r9kTBR^Zu2b<@l zU*H3B!CqCECe7A+;PV`5%RPRjANhw14O~PK$x@+T0LruLr{2JUP3>2_;w6bhasYt! z1DeN6feXJ8Bh6RwQnbg~DOZ=q_B;0e4bmk}#ZzSUAvcv2uh`Ko<$eGb86p`A3PF_d z?uMKOzrdL+3Si&EBq>?6ory_-P{)cUQFVQK!nSxfCXix}7!Gv#zUnvdi6G8%5;%Yp z%jNFJubf7Y;pr`%Pcm#`?=|eXs}30d;gb8Zykf2(7L>^$9UfR<)piHxu}W54aCsH} zDN-jC?d&SKo$RNmoi!Wd_$g1#JDiTdL_9BbPPN-s`DJ`G4?#fI)LXJSw^xwu^->z_ zGJjdB;Y08BfU=g#Gj`yBDu;yHsm?@sH^$yn>B^pf5Vs^^WL(+JfKkI#8VK;TOIKzM z_|;!#8CrK1`iQCcvnedFUfpBK^@bIW8#iJ?p+J0to63ekbyfkk0Y7tbkRG-S^lQOf z8-J(JlyLX)XBuoh3<*sScp@)1c45(VWn)p?;?c;%*%io3RPc4I4qpp(?2YSo`3_5O zF7vwG3{5v}Zh7Vr=4FZdahi`RFDY&d%|`^DI@`0$OuOj;B-3oS_0I%jZjUBUt7%oo zk6C8G=-k-+t^@bXl|dSaNGeKd{|X9+V)e0SIp5cg*_ynP0-%&W9lpc$NN;u3?uaE0!GW4;7=XAsWA3zzEdgpx%WNu;6UCMn z(NDWkzaXb~nVs#F*L}Q!MGV1gdXa8Vx5xykBDve&E}>V%0y>$4p$MR39+X5}SQgnP zikUO5lwAY5Msu_I*`wAb6jq``kGOlWzotMYN@mayeN7DvYLD&swL7I0EIrVeMq+Jm zR6)ePVAJdDi2r9gN+4@S1Yzd*?~}m5{Qo#!rR>)K8|7~rYyDFX-yKehrk3~-MF_f@ zMDo-dNhCvh4~C4MPw_a$bt=+% zgD@5$jSTAQ(HM+x3{!h5r}-;M2~_i@-Ws%SY2y{8lHnhHd|t>vlA=SAcV#&H?NhK zglCf`lz}GKeqXGPU+9cxYS9y{fDPwSW>I$tFHSV1DOz4vHL1G0C_>949linH6X9hl z?h%m~B7in1yT9-FuKR)_?~joKbWT$3uPEBRWL3Bx28}s%;WdH*ij|GVJ@mHd^V(M* zJ}=#g(8(8?Z3{=6?>q;`V#a@#K{}ofX6s_~K|Yq~$&zk7rKrYifH;hC08e;0_%BIA zc&tVS6p3GXNSI+&Y+~4bd;abhW>qtTe(3&HoKOSjUKu0tJfry!oY?jN*t@ifnctq& zP)cK9qPcBGiU)~G`vdvta@2tp-`C5ncNW+=iahy6f-m^qmyKq0e6F`&qY2KZjmFWSIO<;m)D+MqvP71@yiYFq9WrEjIOsPz2* z+KFd6Gxc6ZC**?6h~0NQ%6*ydN$#(`Xn^!`^GT0lP4KvA?;eK!9yt2eLsG#97yR2T zD@Z-42tc%NI#AcTKi8T8eL}3rIOEym75u>&g;p4S+MKd2#v$2m(&HEE%y=m;epl$7 z@O|9A-$0(Dq4whfdQKYK`voBTt>s8tft$U~cGS=M^KzG7I<$Se-g>vxtT-N4m_x;K zgm^y8286WyWq<|T4tv502ce71<`D{DoD6?us+7#KZ#Iok1T>D;1{)dl@D4+0*=flI zgEbE)pFqNfc^MLwb=sEtYF&((tbq8EU7eQ%{KKUTelO$!bhAIa5}Xh~zrB>1_{<*z zU+l=gmJ+o_1Fn&rThbt``lr|)z$1H9|JhdcQ$T}2mEV(;6UM8$ka%ux-SWB;R@li^ zCI?LEyeerv7Hn;HE2V%iyF4Ym?dWvtr_L2$UO#{KnR8|9h-H*_-eJ0f9AiT;R_#ux zp^6UKk8O3Mj)%Lau(5wTywv!AwSR-gDKAa@H=eTo*EY<`@}J-b_#GP}5QOu6M%+qlS+5eS#E% zak+gOfJ!`kWVE*dWMmPr_bFo6sg08E$t~Jwxz3mf%qEWAPzQk~9^}xsJmw-eksz$w zgyZX&ri%mjSuu(aAn-^4eS0+Ln9qRt4pbi!`;zXI+{@{$HNs0V3)E&x&GEG_AKU)x zdC9ddez&GOva8wK_TKBcnkf$N^@XP-i0XM3z%t07Kx5QVtrW}obtP+DGJQ5o%$uEF zQ6udYGV)Y3%^}aY5{6m!-hH{U#_6AX5ud6^+CiGe&Ixn*swHkXGO#k1LhlYA>HyWw zVASBe8T(4_RATVX-;teXz`G&(`M2&z@frm})>c>On5Xh`o#sj^w)jpaC13nSlXBBhzca?fKA83CLdyiJ?TC z2bWSmloyv`pN4-4Se!H5J{J^JBoaH384>NWN1E{llPsNcig;2R>lfGGh!S>jecnA_ zDAqNSGu@JMaaD-BvdYAbM`=!_yreo_Ky?X{vkGc4JY+;fR+N^>BeHeQ!we#Vg?U?F z(5K$67(n)Aa#7W!ZcH_dT8tIJJvehfV)cXjLZqRUD>(>sEoS~&FOlrS@y|Nxhm?}Ej%{)8`fuqYx91%ZV|J6gChp8mDw;eh4<`RCO zL1ra&D6od}(V8H2i`LCIUU-Neg@$5-dcsoJBDH_veNi+aZrgd^{tQsDX>kk*f{xWp z<>7euLiw8rMf_alkDrqZkeoQ|Jk^H%ScrhSC4XZcL=qjeogG2bwo3JnkD)e6BJWYl z3m#FzVA^_DdxX~em*v1FjLvLc=B_Z8@cD_4fKBWi9p8syI9PaD zzUl`Oa|y4T9Y=cD81O3(3#=u@pIjJ!%9W!1l5}?z1vlb4l0Qv6wS0D^#oL+*Vun;Tl5`ZgmM5wM0;7iFh)AW0O^0g9eLMn>~ToYZ2EUm z(drufnf>!{nO^x^}fg8alu|5r-S@qhM0fI&^Igp8l~ z)V5wPNp_fuPAn4Q=>+-uBg-EmXulEJ_?9*94#l^tQM^+#* zY~g)XT9XS8(QZ2DbZ|5zC6rMUmvm8QSz;c4+1$iy zC?}hfx*dX;Km9uAVZf^`3i{-t_<^n-u~__^>lN*1H7|YE}DFL&sM64 zD*U9exVp4-?}5}KKw0=!Z~8vX$;>tZFf0SeuNO*va^^32S6C@~$*jaAm9>@aShWeL zJk$HcyV)a11q8d$+$QD3U=@>F#DY+l-gVfUUebY39^}}4VWKt5+`^fH6Q|T;iDJ8} zal`J0l_rmPf!yNP&pKEL;&ePRp?yxNQ1*-ayr%BIdF?jn06%jJ-N$_M%7njh4Yh%2Bt!I;JR};jtv+!qLLqR%L}SQ zPedqiB=inzz%f@gNCUBiy|}1V5yad!aL|rLSZe_i2G+BY45qm#k!@O-Z>uRC>hf2< z^KPf2daMX#fVf_wM@h|7F;BND@#qL1uNgOpiC#w}$bfpHsZL%jUi~Ya1P6ae>`DSw zDQtqi{rrWPXODlmp5+)|q!3BnbWm;yOe`Q?bANt!&hZs8qP;4UxzHGW<^rG}t7K1G z*exv(NMLZ!d#gX$FNDpq2l2&!6P|e0aq10W97{MLrEPP3%J~8NhXeP~Fys zzr-CZbTrdMPy%~1T9x?C_h@l3`$2*&KU!D%=%#{+!)GVuc^+zI5a^-3P`q8$@?p^f zmXiKnohw=3%6t15RC_q236h{4eeXtmC!2uV`SE!nH9maTcvP{;rG(OlEzp*R z$cqWp01k+XdX4)3Hj}Ef5}{_!j%s9$4d7ht{nKy0hD1@{$ULbS_neLU{}pbfj5)M* z^0V7sC+*vI>9+f>kST2h!3J@wk3Fwvg-84qT7(^E^2Q>z2t+}()d8tHG*q^56-gI* zs17e^iE%aDk~et5RpwA!nxVYqtwX1e@o(R=1}t%k1fQ-dqA{3+l?x^RVG8l~X_nEsBI(IDLe(G9zYZ{8Df}Er+slJw%{T>>JN;mu z2Aoyb%7EYiXZg^@IGo86AVxE%L5@5RV%s0C%U#*oS^ov{SI12KM%AyvMEmz1l@v`f zwXzxz;=W-84hMIPI?#^#ZUF_?5fX+-SbKXsdt1e=){<-P3V~~ukjRIDmlFW>JI*KB z30v7BBjOQ(!Y|iu7yprNm{#GjovsW_32?lp&-U@B$lw00a5M9ZUZAy!b(&HX-=qO1 ztEpO`XZG|@G}B({XB0{qV(|~db3`2BNzn|~$(kFNdCej)oRcFT7g@v%dUv9mChF!` zc*bci6dJ^!>FiVyok19kpl@u}AorOKkBv5C>7i%gFE3X>oLR__sPRJ9>B#xyBjD^! zWt?kx5ZT<8Fh>`cz{*N)iI`wl_8&#ckbk01>EqaWH#&al!K)#tQ8>fXRPvj77A_Rt z(rALpb7K9qFd$$#P->0QBxV+Yrb;++x^HyYk_|pK z@lIPYuL$d2)g@I-V!f>vQ&Vz#dZ+SR^=W-S%RDhfyKW#p99GiVuXEcrwAezS59@QUb*IaF z#{E=kWw&3Ukyb6E&6F}U>PijG;BB(k?`Tz?N5wW#_0zQwkhH5Q!;x%N9U7S4GddV1x5o%lH0C%j;|k2}owG5N=tRBWay;-{Oxtv!c=SL4Y7idy`eOSf14X zhafxb{^_KK#JXs}#sb_(= zZlP*xj^r8{>(293jJ8(epb7KGF(7nBK8^yY{Q+`jR5f`hGx0B*jof!)=zzEus7qb- zhJrEt#ST@TOiuIIDp?JJd9Khvrk}hJOd5-{ji>EsA%JBzX>1q}_@I@+p9rUons`{v zk}S~_HIwW)22M4V#wMvK%(%BipLP1zC;`A262`qwIHpqX=8_5+^ z-K>(v*oRGVO)Fe#D#VLygVh<)1j^JZgwd%_`Pbe{sUymIU)8dipw4_!Sxd zEA0ML+>4Ey4SL);dLHq$%9x~ycq)x8&_ya*SWy`n&IryAppMhaVZHyi0@Jurm=_{{ z|HLXAuk(;TYwf#sclKEM31IUAST@YQ*&RDy4qs(&mb;}4O%K0&sECPx+I0@(+9=6K zgK(U3Rog@>fRWh#Wy4<65GmykfM`-GpvOrX0EpR*<9fSe7quK_Z7!Nhi2DWQf`%0fcjzaj&Ki1k1E> z7X`1gDQJ}@!LJXf_ZT-tIW*~tof@{dSM{aWnEZukxaKEUk`ElQCH^i;Qs4{)#?p<< z%ijr&9dc)H^8cqFf?Og;_4^ms5X;ZHm_=^Jy42hsBzgvvgEK@oC~*D|b~eHX@?nir z&&u4#3_@P#EWCk05)cD1sveF4=R$qFO(vG2(X~c;Ml00uCbk)wEWaZNu8LO$6W$_27pC_85ohtm5?^7`6pM| z-Ql2>}l#OjcCUVXD-Jd6E(5p^e%x7-IQuA#8=F#_Sxu;xY?*4xKXX zm%iCuKv~+J$If3j<3D3ni2DZ7?5(brwKXzWT$C*fta6-a=@C=wf)q{cFJ8V5s{}yu zbP*8CJ$!Pw1M2NSrb%TvLvaQMtbDW+VXo*l+aw6dq_?{le&j@#vEtue@`2 zW8HtYQjh!nL-T17^)%(hM9=t+o*m3s3d3D#+;FE9BVV zP6h+cJA??mYOJGg2`UMdfdef3#td1H+sAwOw(Ta#(J5%@!reFJTIyUvZa($x`&K)H z+DmukKEEN(;G*p@cL}eNut6K}ujq_G5kG%>*@{T;%|UQu3ww1ts5{xWxJW~$##Q4W zBX?FmWvsq(7d$PRx}Y9TC$Y(n8(2ux(qHCUJ<;Y|!Onf(O4|!}Qhd8Me~;tG?lfA$ ztDwLLBjfHSwl|1BPvx^j$`mZ^+T%j}>nIk`s|EnE)?bSJr#Jp=C3w(5*jW?ea;N~B zQcn9nkn$flOtW!PFp^wAS-Q|(SPNTI+N7zEl%j5W0IlhZ{0mmi_a_@vEHR~I^3aqO zf)El2PE^fL?>8tyrx^Xim+#}_<|1Z`vL|CWIP%u!P(&yuW0<;h=f9@s0=-K1Cds98 z1Xa@buXpN87?oy;43)#C(|3VGY70Q32a!0$PuSV(adLC9Mh%M``j2%G6IyUw3Wgfr z7p|w($@da0a#YdtLJTzzIVq3RHJ{pd7fe;auCjtZMfecN;13Cn2*$!VNhV!&k$t_8 zR^@BD(!xsx0-MlJ77QuU5Z8kSPHrm7&n5Y3+uLD$)tE9l)E-3eO@I%XH~@e?2&dXr zp#o~pa^#cM7-qq0vsq-LRzV+#UNG0PNdSubM%}XkV8i2vue8Nll;LKDWuTYS_}8?l z0^e|1?wFMn(;o4j1Jd_NdcD8^LYt8EWX3j;Zbka0+B91c$eIDpY1PuurwE1k2}l}a z!A)`zQ^`2at+S2!b)MoG5DxIQYbj@`8sLGGZhur)+ni!)k>D5nR;u~uYZosVRi(rG zWJWe&xg2%$l!ao<`in!55$|N<(B{cUrznMKKd<}_+!QIdHd4nFiRg2kXZ9_8#ExcO zsX~vt=rWi4*}a!uzsaw6j&-Qqwx@0)S67YM81h#|v4Yk8cyWvWl^TGxF``g9>6MH| z-+YEyNNT=1yyqc6Gq8{SQkA92Q_dTc5^dfE|zAmkt_ zSL9XWS6+S}pb&Nd5IJB*?9KttgVjBGf54xTgPtU#vxJJ`tz?0v9j_u4R!-H*x?6JvKFjtQ10t?u2XL zrp6`}*FfXS#kR7Ovfy&(&B?^(rs@18IWnPm75mGTdJ@3WJqJGWggqoNDTaC%ltFb7 zzPx{A|FU;<^kW+0LqNNH7U#Okwu9VT+pXZ?Gk}St+M7lDFW(*sM&OvtK(IwCm~zk- zsNsat*#9{(K`7+<^~o>o`tReFmxhnbqqz$(vPK3a)B`%4Vw?}1bv;hv4e|Ts6&Y2i z3pueBAo@yY!8?Uq!3Im~E1nL#UY==_%48MLWjz}5Ig2E`Ea@eh*0lPvYg(CQi4)80 zR>J}4(=64h4|hP-zr5*0kg633{Dfb?E}4LG0J@$x@&vl$IY$=6pk>DsMjk9U%;n-$ zG#MUXOdgfoC%^1hN1cMV50B?SK#pj`(SJ?@h{5VOT4IwBosiu=Lh{72%|NCF2!-2l{;TbX~j;RrTZ^n9as@i4T)hfKWxY3;N-HBtGuK zB6k}T`m2Z16Ws*4-s91T#?LB|@&tvNf%Vin? zNILhdTE+#89Z6ZRxsuvS_6c|VqPD{O9SdI2wXxaUVab;=@Xr!s8`_}bi97~3Dn7f5 z*1&0dR>EE%y9mCYe3^3G@!gDIstI+-zuV5_%`e?-=$G>D$P_+WN`>(7wkr`_in_G_ za_zlyC1#;?=c9P*H^)g<7^*?C+^G}*5IN=cP$bm-Il6CJDA=w?Kw46T<09!+z#QfA zoMU#GU%AyLj|*qnNAq9q;F$09a>jks5s-O;;2dR>|%g8X8XiSOv0(9`P4p~GyBy7PkEHvOAzcY$TJmzQ*aUzWdUPlwHiXKJ*jVVlM zzWXk*O5(oHUrQ`+AT??IU@A(&hcx<*wi-up$e|-ID3#H89!jMwx3JC}93QfCZ1XCq zRD)}~18OwZ^cteA7!e(vf%MwztsH{E1X5oxSW3^tPT5?B!q}YyixYqJuT607dA45} zb{pWL9#cR!ly`R16|ipK+PX&oK{=Oy{I8aWW~L!ce3>v6+m8wQ!A)q9%^G0Kj?3p$ zCi<=?Y#LID3)#ctpYkKYcaMp^HkylHX8?Khi*r?{7I%_PJEPh*{ZKyNE33O{Kft=q z>66_f-};tjWY%(}(){uq&|V*(W%43GLZa!25J3PCiy7XgyDUTP+}4QDqZvrdy!z4G z(T5`5m^1NImy%w`#qu-V3OVqvz6Isjk-u~9%Lr~?xT<7Ovy2fk-x&HGU;$5_Z*IU& zS>K4%(ct6%`>2C3Fr@g?0#hO|{J+9x4F9+9K)u%%mmRM2TJ0qDAvaE3ArXeeFQLcA z4+F{?(%kB0XGLq+yxyvES^VzV2X|e<)D16+os)$hv6*9yB7Cnve9E5cCvLV#2FJ=# zg_R#ME9$6VZH!qFHHy4W8SSa#>^6*V4a>Y&S`*F(mQm4wq69t zm5qoRM6YLTk7pd(u{@LrU*YTNK{MbdMMVKqLLU@i(qR-5C#MWDT&swXW&HmZfDz?kzL6KsgxA1Z#YTmMg0|!o zq+|n)jD?2l?ScD^4Ji%x!!Gcbrep&YM8n7??`V}X@bz*kCqT=qOJ(u@+vjKNN17;O zh%iFLfcmp?!a(l8fMp2+MFbiMZwd;VoKYVHP76Z;>#i08NlJ`h-4?1~x`EAl;3>J& zj?<09l;O17xz#q*I2oU=pCOV)sx?qN`e7TFz_bpkYCK`;Bs=wF24cF%la>b%o8)2E zoJ@fEQv|tRW6YtES3(SyAWDH;7q848J_tk`%L}2L^}q;Z89Zq}P@ztUGDUOLp)Ae7 z@Y4WM7{*937kGJtq4R<*tGK=@VZaQW9+3_-$r`}hDovf4V((R`ic0J~M4o!jBJ1i( zzUkyPz(CyUv;28`tcSqW8j1)2ny%jN`jgG$;YcsLu+Jca754W!gQI+}R~08^5Z16h z%;;8QZ8$f#D~OG*`~`$Mqm{HPAcUOGbbG7GSWcV+bY;uC*_oTWdc7Z90HR%^mSRNk z)b&wU)KP$Ri1z?U#JluyGtXe_l+q?3xddzImZeAFceoX70@-`++5l08XWqs@9>aV2Pdur7tNf<_ zded(jcplWTn>hz<=_S&{iq|S*I;v}B%~Pi#`#@mH?O($xZh7?E)~I#e(y3|3?Q1yn zAK$q@S@cuI5xQ<1SH73J&eJzQYtfVGO1LDB50Q7_)q^ye1Lko6gQ_&;8q?9<$8$1e z*KVDOuTxhy*Ejg~&H2MY?P_-oT+V>h=jw@^{dU* z?TAz8N_RNWmc}}I8On{`l$B?@Y$V&0)Xt$d1{{OE_vh=+!{Nh>*NJJ&<86J6cw!R2 zndG+sx)6EnsuV$h(Q(rOPq5u1G?7vpU{(WwjfP%g@yk1I0Tk>XQ#H^y&Cs)t(> zZ+P)kDNW7;9_z+qTy(UM9B90SIBNsFFtYM9g~{Xy=zVH{QJKs`IIlRXJtWD2OCRjh z1U8*8746WitpP0##R0_yHad}3bOYEN#FKQ3p!Y*DYv+O##~5JBlLnxi&tOMZ7@^ z199m-mp)XG54?|mJ%pBBWL?e!a`k9{TA)WBvCW-iBR=~}GDY`qwB+87_x=#6;;1+H!fY2 z(5iOS2b3mcw7+i|Tb`q^6=X^5wS92wYREY9@A|#zY3nf#gIgxG$)X~PfD!7HSJZ6! zQC`JK?Bm$nu4p)Vn|9&1OP1{e&Xd}rNIJalFk1n@9~Y|D|9{{WD;5L8f5fZ*FYt;Or6nrJ=P!kaY{f!%?-KNu20zhD2{w)wfkx@o*Bk(Q?CsqI~ zP@o9c{+Vnkr{{DtN){KLK5Jf5Cndc@nX35MLgbQ)j zYHYo6@ZYaq+cUPhq{YIyca+a3IcEb{ORpat{x}M{%g~3T-Bo9?#>v$fe)Hg1WO&B6 zYrfyhPe3eR-}jZFvv8mdIErb!Y}(qeJ@JqAb2VviO%tQ96{NzA!)(J9nfGYF__VL0 zwWTGj7DbX;0+%jZSU|gp8~s);s`}1l6Q6HXu{ml@O=*Ql>|ppZS0?M2RQv{ba)Pcp z0qRq*k_Qw0WZigR$PjG0*x+TCO?4KzGwI9AHy1oC()Jlw^a9!UDrkS#+r%|P5L}ze z-fDfH$Q^sN)Jsbprn%;%d>tfFIk-7P4-5P&KT^_8D6*)r@3*S0iXu6_{}hL(W8|RM zkVYZOMxQ>HvH4{-_?HONqOS<>K@eP@uS2=6fjI`_vmI@*bfo%N3b2Cz7anbA=A*IE z=d)F9|5R0)Ze7TQ0gcjd0zL-1Uv%~I7lm516otZE){SMygJkek31UjqY1{(!Vkn(~OE^4_8X}TkT8Oh)EbT2v6%+nP`~`ld<8kDuX+)J+ z!FS#yLVPwUOpz_x;ps;fIy?_{O|e zwz)LKdkzkL;>Ol`{QzS7_wWYDZlz$`3m}cm$|%zjaHIW`!3iUQg)7i2-1o#nXaWC& zP5<~X*l^Tgf*wt}1CkWFu{pRHP^c5b+rtB^&U->*b3$_miD+*ocm>_Z~aECXA735YL7a0 zIaU1NNbQq*uXqXRF=Vcd-1nWSRE2w`wR$Q=%1qL#cSZS|8{}hBXb_bTDX%btvv#E) zAp#oCbvX!l9is*bhQpIZaPEI*;3fPv_@sXL!OKp6>%V#0^z1rOUAV9V9D0BhOUGDe z52#ZDX~@k_)M}1Ay4Q>gjaIly-E*%?qXVSTP!oiuS6t%*ix!?-Mek?p;&6bbr9VN) zpZQ&gDrUvXPx07A0*{qoWcCA;6TFs!87%YkzhD5WLFzY}H2YOmo*r`w%6YYhf6MHv zOb5^f3;!t(J?dlF0H0mALS(($t=rqvD=GL^SGoBr1mwRguiHdXu?@4(&~sKU(#Je;rccuG-{s--9@@W%v!E;$g*xxn%Ysg?2=F(Qx)AceejL6D1UGL%=$W`e(Z2 zv!b2B4$D*n<>Qs;tBAw%C^ZDt!s&lRCpjxQZl(Aa1X;Q@ipi3q0tJj?&)W-n6aoX& zWBMxrs!j*cw9e%NL((ebLNr6NIfylEk+;T67|0lTPma^1wVqi@a4Ja(ix;afwg52R z2a=BVU#3U@3Y%uGXp^$}v$VD<*b% zP%lqkbFgD$E;O|BrQ9CG*iSHfC*+pp3CDFVTh{o;qWmc|)vejok0_y|cW3q&1%=pG zJiDlBIpqsC-0c`*W6C7{=^UkR=JJ)I3V#J^FufN9Z1^Pk>Nl4*6ahOKF7quT0Bu@n zFSmQaWyF7q5%gq~vEDNpp{P)D(}T7L4!h%YlBe*+>T3lsXrf`jhX24921e>ry!WX< zS=j%(?QGH7as8o51-uyc7xAN3y$6B$oKBF-A3M~paNIqTw~tXtv}T$(0l(~jKj{-+ z5{cNqCHq2$SEt=<=wG#gKu!Qbauy*r%_*+XA&?~pM;o<5k>H3K$BK*vYolx?tc(>d z(###1$rO3{sZX}q=B`vK#C#42bS`CT{A%Sy0}Q9sH7OPuS`_t4f*AyZn&gI44Jb1i zCS3RK69t{*fy8FShB(G8@j!{gto?d=^)W~t zv&?0@P!B1(f%=w{4kat{7;`U8TXLS@KAYw8e83wVoxo+xp^;|Lq?vKIm?Xw% z2B5++D5E)R&1VQ0#p{wTvx~4qzi?RhP*uYt@^bvd`p&jbP5NXb&E%dT9-#M3W6mc$ zzQDxqak7o53X4PHxcq#9N<&AWBAm#jT%30ihKKL8)+V~(#avU4uLkAR2cs^#DknmR zq?q<4-d>=C+EQ(5Z1oX*FC^ifVO$s90YcO_&TcfA8c^OO$ZGjWDM7IwaX(1r^^HCW z_8yVN&s;h1>!D)AEU6)G_vCpn~d5Tc=i24qhGu8OkeC*4kPznXO+zX;IurAqbdD1 zS>-QswGU{`Tf;r(PZWpmFaDy3DS;!`ENd%E;==mh=5Q2jpe8y+u)7^8V@Ha@+v+K;JR|?~JHwyte~ zz#Lx|OM)R^e3V$MXktbKR7oenqd?Ga^bierbvDUI@=^IWX1b9F5QH;oF5BzW_S-w1 zCG&SXLhRaO9h!$_$LEoF<&j0Xp@?7m;xJjfsOst=b(BRix~xWQfSCLaS$+FxKIw-N zc6QwE{s$K?@F(CqXi?An31Px;vzT^Q4l%i|lS^}&?bC(p$ip`{UF&Z|s>@$xnEnicM+h?yHs+gy5 zz80!&7rGY$BA<#q05OSJ*9scazttx9-fAki`ef&}+U3g1tBSWn;vt%8$CwS^U)+rr zO`SYB54ABUK0~|X-;n%J?C9G&4-kTE;b@IZ#~I3zD5z{WhP8{O+W^Nys6zRQF`?Bj zgm#7>es6$_T*nR>{$=2s;2|!o(ErnVf&ajU+5g+m#KG}jE8@@OITYYWeJ3@gMMVH6 zh37L?ET1h}+Tt(EN}v;Jr$DVjT*3AJvPCYGRZOMZoMLU66$3rc=R&x1-4-0r7yH>Z?9J4!A{`DW+{RwyoqjG{bF$}zvl&E93zTc-eNH{w)f z4Q4si?@Z5@S6AWOwC1`R6Mp*^5}d=Z9}}KP6`hTb^|E+o*P5de{OX{u?*NipUjkdz zzry4W@xnGK6nqa`hxDBH8anL9G-icjq^ph?Xkp+vWLwPQH$Z7dGD%eNrycbLdCIqc z&Iv^)%hL>D^rl?qSmbV(C55fX{JTr>Ky<$kjyRK%nC#oBOk{a+fcl`9?db4`z{JRy zho5h`Jo{_kD>UJy?hr{K*x(HcJ>KNE7R&jlc^7*Nby-OqKO_;l0+eT(3xi}D0ud;0 z>NN>3wz`6JA7B_v3t%2exocHC_u-NqK&A%|9FcqPJ>V{KLJQkutWl zz%Oo2A48t1nrlyHN(A_?Hnq(`q@t2vI|_`-y24Gp5nyCZ4ch1(`-N@bgUES&BfaCa z-#qo?t6A5XN?RnRV1WVN3$sc_V3OzNKqh$mw(c+I1#}DfqU$%*jlvoVcx!>&yt}EV zx7R>mM01ZPS6vkblDT!IeiEg1fMr<^UHjvKonR%qDQT`wNXM;J(Zi~-IE_w{DO*~PV(eyL5rAB3guZf#779g_y%H&t7Qcv-Xvm*V z*#|t>!C4&WZpufMCf(puNJ>9ig~U+F!3@|+pT~GdW`W|~xC@pqo3dF5zcl86r~aPR z*8>$X={8kk?8pfgfmO~}F})DFjY`ffR0kYoCuXRBvOHb_cgg(%1s+@HC;sQrZz7waA-dU3>KP~9SBl7(Vf-({no2m8w}_!Hhee> zO1tZPM4>?GT#o@-BC?3Rlf_p&7Oc6T@Gk%D!uYi5(`X}}yF9I2$7k4FPa_=yFM+(; zJS7sTsGWM<-%`3(ef&WECx55lpuamGi&o9B%zBFRPaRI!_m@ZmhZIZ1nfwxFop4e-@1i zp=q*x2hNciv$HR#xx+v-U&U=0wznJ^DYEjAv|B6-pf<%lq+#om$YFb5g#O{P)dEzP zKx-34`V}9Bj12tPm&Qy|$BNZCl>p*~t;j_FzcalGLn4dJllBNN6pxTFu>ytE!s6n&Rxi*iYJ3U&>WdnA9k%39?ECk7-VhEWQxq>v!?# zeH?toqy;@A;w!BBg`*q1+W_0D(;mcr0|C418_yOtT4f_v3AdcJn)xKw*?|?f0sN3x ztAu!Vmx|Ep$)PGa;GPo5qGd(Wa@@|39_r zKc$N8zs3vLe#Q)buv365ZP}D;iT_dw{zq4}4H}`>6|d?{UNN*hb)iCxNOc` zj?snKw)QioU3&2rTuJ4pUh+}Huu(i!bsv`NTLqiTwvIprh(0DvbF>how*<^U@qs}O z!5m2$qZe$R+s{>T_7_8ZPfhq{(%Gx{-qx1yxh)DQ9SQ`Orx>s~%|y2RWn7zW9RN9< zr4|Pd^~|Fq$0d zM+@Go@@~EV>RAQSs1b@W3L*yW%f?pD?rpz=!08zPCeh3-IAsYZH)*a=ep5I4;Qk6!BUy}ey zVu(ge7@v@TVvLlITdEnqar-#9QLo@vK^KmlZ&DfVCwmr{9Wc(BwknNMB$swD{(+DL?&BMqSpS(J8#*?_$2=>wMu|P_JN>jEI3v?NFsUG;$xg!nhk=y_%IbI5t6Bo*;T0T zmwNQ;+Sqrg^GApy6~mLvfj=X0q^JkHbpBaLHOxOl&BAaMD?Pj59sELM+HADZ6tW`B zbWmNYnbzRH@*4M|3I%ev+1F0?jbWbh6XNW4U5pjTKHyQ&i@umkU@iXhCu2?-y!w|U z11Y|8M}Mt{SuL{v-yr$u-}#xhOKYJ$+?JoMUTYLD-q|KY)UJa8Hc@;bu>KAJi~Q+7 z73mUAWv>eP-w9wgSt``PI7o`8i!U~haT=r?hjOY;0p3UQO1B64eh(d${gh=dN}h@- zfH_URLrwhvyPMk8`f7*jssP#b$LZI(JeSKxT{q9be65rPN}y-` zq%}Q`=}Ra9j+OT*Wkcd{W2cpX6}3FK^KKR(lv=O0-NatSyh8~&0<#Ah3 zQXZX!5yn;U`8T?pO@Eq@_FNsdgZl8)B&2Mw&l%F{sCv-iMJO1$dR|q+obU_*>U<|v zF&8;E=VAtH&q(X2d&rW(^{N&B63G$M-0ixT1@iE;=IZS{IWhM{Q_7?PhOC#c)h2ai znCvo19X*v2rqu{s?!*cG5_BEmjE{{xpgJH{K1lQ7QcjCs&we2L?m~swbur^TmK>al zQDi_{z+K+&^cLsG$0gd<9m~&K?wl|CL>N*o_w1fR5=g^y=AM0~)c3YFQ>30RAqUi1 z454F>gNeI+X$;>ChhIjF!_*|j2|5r4C2}h0BEqXJgPycOeS)ds3EW%Lj#YMsk9oC? zcWpIing4*bQGO4m5M7~RaQ^?-JU@A#lshY0z>aFR5K_R5p>u+nMB5AQb<4WPxvFjE zvv4j#vg{OF5E}D2V27Uw1}aNyBMRSOp#Spf%D?l)UpxO0vfyy=)Sk=d!2oP1a8579 zNhWl@500`2P6$VM0Gj&_BgNXHC~9itV-vA!kgZ2&l`P?2JL~e-O#IcRM0#u29#ZTK zV4!HO)9KN6$cbDA>n>LnTHr~#3oAEAnWg_kGBlV8xSgRIL+l)=&h_5>(OayF%9>wi z%65(?FBSwnfL5t5sXCkiEoao`0ZTLgk8s^^^XB%U@jH8#;aUirwmRxLEI34Sn(c>b zrIk6EjRZ_AVYR&m$FwXi`30?Q?6bojpc{b^MXqld!uiu5eTw(f=}~l;BcQS2mY?@( z6))Hr#9#xDwy`a|yM@I<3q;c_kC{p4S4!cLOF+z+CR#rp>(SQXlD>|CrfDr7q?0#p z*_c*GnUzhGY;{rT8`*e~1kx2Pg!&HMs8&V-^P7>FdQ09&tdBAVz1(%J|O6M;jJYALyZnx|x$MF-xCFySx9%_hOJU5rwF=0yU6b*wU zg=ox$vBC(rq6cq7(y>$!Z$l7$+h8j)7ie?uo3GA}4o3Un`O;%($nsUz zaug8Q_slxT$kdvbA?zI;VE-rxQSZ)@scyE>>uPzh_@92nJ;>yTmFs=N&c@x84{A@$ z&DHwQ=gmh_P?2YN(c5eS+}GdR?Q8a`eSg~fE7M@Pj>`+FX2bzZT&v>VYoxv*i97{I zlx1sVs1zS&_)du=TNM1kJG?W6(ary`AxjbZQ9E;RaR2ydhF?p<%4PzFf9{W?K5td569XVq8FmNr-q2-r4{W`V1> zs6SGl5EAeJd?J|Cu_%TT(#UTA)V_R)dNr-1aPf@+=A6KScg=b6U&iWdg)*J1<}c#e z7lJ|E6Zum=Pe46%Fi@)kcB)h`l`8=Oa%9{$29XpfAzzCIw$T8mC5!+!A^swHWO$Sd zhZGts0;ovP5EKcGeJibq7w)&)&Ar5KKlwvFhm@_~tnwC?A|5I*_5fuO`u<;>r~>3L zw3qmMe+`1}FrmN0E6-}`CGo7&{t(=ypeL)TaYYo)#()wT?~G2xXG)EhMiu>4*P1JA z^!Cw2U#nPm^$RaM4F~>f0#E5;l`1Z;&`z4I3uW&<5LA#7ZZbHkw-^$Mx%7~zyU&uv zh}0NC>Y@UjWJef?jk=m5?_*(2UQv#ZUWJ&`Y-DPC{aU#Di6iwQJ2Bmv5e9|hh9`2e zoFALwD_|-Ifq|ji$X<0-#(m1U?81MEDDg%j{o}sS^%-AhR7J4}Vc`g*P+*NUQn2hV zYy+oK;vOtBOZUVo*Fn!$L6R1whY$jH5OhQin7=Li+`xVh|02&)-cIj?t^P0B5KB*g zEIipkFagmtVu;e6qnj+u?C3dxxEO3kI0%7EQ@{-sF)J7n!NVaY7kzmH;%7KM7DUd5 zZYABq0a_5UimJORHLU>oQ|s!=Go`hxX7SZ*uI)elIzev-ZDz?a)=vrwN4n8fz^xPO zU$s*CSMOlO4OtO1uzyVQ29oz?WD6@vpM-ITXY)hYWc$Os3zsaTP(y!g#n*2$VMw-) zGzfn^S(p8ct&2r|xDM$0YYcrf>t5{dZF5e&K|-zvOQbN}Q-L!7pwIr(J4|WWJN~F{ zzpo7&2pe=bK44_k)LkzBq@O20qLg{6=%^3vg5|;s^tnIWI2vI>GC5rJh{dHcB^p0x zTK>+|&(8N1o6RO*Uis&PRtu(l$a1I>Ozt`BHrM$jr35syLlVqCBYZJ$8x&f!%Oknc z-Rnb{vOSkUduTjkjF2^%2)L!vNG2II%|MBw0PbiB2f%I1E7ZLcQaZ|d(lB8n(0*nP zg*uzD#`DXxd_1iQhS}b@&4ZmtVRq`_!PNF-$u@{`2OH8onw%8ftqs4bJlY@ATztB? zJ)BguN~RBHKP<#Z?~pF%zp`?7cFl52Da)>v{??Ref%U75#(iI-0ljAWX86?G*_lc?>&%@{V_F|sjI1KKq~7IpE~>?;1Bq~voM!4D z3ef{ip9_K1s^#=AogGqh!UGJ@TYUccn8zw}EkXP`9*-~aolMn^P}-ilRbB2%V@F*j zbwKUQM-0*k{>TTlcm#hsx0)K1o-HMTAQJ?2ituuA&wW; z@NQ7g-nPE4&M5Ct>4iHZjVw@2@{qP-!XMue5W!QD;Qg@bStq^6WkASsXUHl5L zy|L-jLGnfaKQeWtm232jzgx0MghIKlR{wv-+cRRabO{a0& zq*Z0rIhvqoHN~RyT?k6iNWd|{r!-8KLk$<WhBAYhd7hgxrv9iOqjDIt$xme5UceP zr_M)fH9#rRrd>e@-%A-Htdi^1?L3P9F{WcFeiqMT*18?c&6kGjmlmB>+63eKbc(Re{ zpBrSV`;hxCRG%jeAYFlvt5u~%et!n&yT!tC$J)lD)v}2&r(wd_s=;F9f^B^88a-8I zhkF+%X*Y!U;L@oc4VC0~U0g)3CoZCK8wS2*sO7~O$g0zy7{9j-_tCbEqA&U&wA+S0 zdw_Hwf6ECcR^uyC9~KH6M2vAN$K9PNWhzf>GxJb%Hqn^G!d6NvVGpGMJUz@A%t7?=dH`X+R0YJsaznOg5y_j)7`HAYGTBX>jB~fH24B@x^`!s-V47IVC zHMI@L4QOL{VFJ>ZH~Mct^>8CU!g`;J>Wu2vMcD5#$OxL-Nsw zA3}?K;;XXM)o1HMWD$5U>k+Iw|Z-i20fpVjnQ*6&&PXJ>p8?bflF_ z%fZb>@fvL5!xIQg3G+PUq`&6unJ}lUyHS0EcQu%!dyPJSWKyO&YyxPK7_trU)Z!+a zs0qGJQJLW`_LTL$02<1S*>TwXkS+Q9>lo{6CN8nW>3B#=CE$y@0c-DdO7k^JSxF;i zmPnqjJjrm8((aGF#mWR(no2VG@+O0Fi3zE52XW+3rnR`f<8D0xyKdXa{vLKDH_-yz zd=XJ0SQ-h*Lo3P|J{17ln7uaDllw@JfLnHMT=Po}?KPX%=)eXWwnoT*2*26(ZTU2js$xs4C?js@eX?Sk`hga@yc^u(HQoP(S ze_%dj@oNz(!235!7+xvpYqq@6+M;gQE%J=Vkgz4lW&Ns#L|2*GO7bF>q20m-Gqa)ruVx8iun8Iy(9MxzYp7uuHVg5cYo}A zUJta>+w+BY$qU76Vz7XIfmnGO^t7)Fm}4Q+A$bZ%3ZbfXhvZR&ecmX8>Dj3S6|%FB z8sKlb0BAK^dur2iJ2_GDQxJNNV?fP;BL`Qya9KZ^E{-%oR7rUiQ`Bo{3*^OXXe%@s z|3u=fNgwk|k3VZRV!`2na(UJn_BnW!|##$10`;3BXY`;=!v(S_S_$q#hY5fja ze7W6VG&}b|Wn@v6r%O7m90xt@W*~&O7McUDtoOeo=28=Z-0{U?H1le3isM)9Q>!JT zMhIN?c4a&u@;y|78PgWRnSp&$@Os*zf##Ta_n|o5*|B;K+4=`!4bMUQf41)_)UB{7 z7u)dZv2?)r2>+M(g^iQ>XWWhk@IwInuT#~_hHg5~lZJ!=s6@zE2&*6>>7dqd#P}i# z3DmJfbF#OWuka{b)mGNnb6G?*$-~hfB@t&ri5mj7R63Ezyb`Vg`C+WtDS-Z#Za$(*P}P|^HKAYDYB^@9M^-jv$S&9Vp3Y=WlXirABv@g7hwm!3weT4 z2+sEiBX;Wq36dw?2S|V*s=*L=SDjgy zh)oPGsWjZGLc|qPsi8C{-=Ia*%DsRbd^$2z1oOlM1U&qyj|vRb6g*R&I4x&*8J?@P zWqtq&Xfe7>MwAUnazwTOyY7@I*(8XZR7alWylh`X)|#xujimr5+qix$Ytp4i zCL+OR6fK%%eul}+;r<_Mv|G<$UcI{3y2s>?w zygV*3C{~fzBSe+TfI0W_G>xzG=?q*=&(-;ha|9!(;;;VfaLeqcvzQ|eys*8sltHE+ zkltoEAkORU%r6R;(lIS&j~Py+}8K20{f6C-B3ZkQyZlD*YMc9MeYKqmqE>};>NRck3?O{IXzn`;^m z+k9v+C~=NuebBrx!%r(+YV4)ZMy_RYe=e0CRmGqDFG518+lNf0zxU%>#sy!aN)KT| zHDGFQ4uA&PQXzgpK~Vb$Mo^JZh4(=Z)*iF~^8L=l&|vHAe9GO>a1-7r!G=JXZku}8 z8KZ*)`*tleF{e`(LmSNW5#UtET-5*P&wA1d1KgEh>tO`ADa0y^C}B%v&-nq%{7wY% zSJSI-!y{v(ByKzJSe<6nhXZLf=X{>G#(Po44WLwTqU+Ie&6-rJe1JhgsxZ!$03k)Q zSWgenI)TIQ%Wzrda6||Cs#9a&Vc90QXoQMH6q89##Gvu1+(d8aqZ?6VSz+>1p}!&#S}t?bD| z5J2!7A>j^EnTx|#VNc>14_lO(!O!q0#)md6mD}t zLXMXyNjI9FHrgh}EKk5Ep8e&f37I0`^_KWIV7*7bZr|tOSTF+|hXo_~3Rbv@1mNKN z5iXo+YJb#urK8^?_z#UyVdj>XebQw&I?v{lEwdX2g|g zMNe;*YW4nr9g)L%CovY6@57eSd6KJ#GsiWXy+G~h;uZkNCZ!?a|19^$_W${E{JB2k zVB-F7{5Lyu3bGe9KzqmWXCL~LeJf}i6Cb{dkctLxj3Ai`F2rhOSRGs^QKI8nGLijV zJR~3Sb;BE-Oh4vk*A_KrqF79J?)9>@|#uM#~aeQf7P_hXujw@7FFRuZ54?pWbFnpPusTDYnNHHxr@w7~hY-dfE8L zcP2>|E4*N9ZJk5$LajhNVlAyj21=tVu}buKp^% z^8#AF4LxilZp*N}s3H?x8te_hINi4EXTRMyW&)Y$#MiQH_k< zU=s9(f6PP~T9V`VLC5$BV9$qx8lvYQYWNiNRIpXd5D8+|*;`Z}i|-bXmi$W?AI>tw zzMB_+f$EMWs<}B@HMP<1m5Ab`L`HXq(ciPNN*{=!qBbt6Za9&nFhJSn+shm^22Q#G zZji<2jKx6~hKyS>8@g*0_GvuIL1|=B2<#e7sPM2pQ^{Xu)W^26I6}iCS(nR7L+&l8 z8d4bIq9h*X=f^67ntpc!k2EyVMkMn$IT`9%sEiR>Dgg_BN zq7x)%OQh}zXr3{vp7%$V z@in|xo!)(A-b96=9HExr5j2gMqBGnY)EtrB3@(1`y`Ihw5Ie{*IOWur)sY*3@FL)a zX`Mv(`KA$AGp&#Mh)n?rN#7yn2vI2Fh}B#RhI=c#`@p4DgoReYvHMAdN|NbuaRd*+ zHqO6BM?S)kjRHR?hp_T@nMe$KGM>v2_(+w}zA?4lLi1I!u%0?O-SYh5@=Bip}Q0x?SBzv8DX*fjpHYcP*5eJOR(NjlWdaYhOQ?a!@c+x=m z$ajPHVPi6n_u*U>2*{8c_e@tLU$28HQL)oqxrb2y(<(uNhlLqaud^7y3=8fQ1F{g% zT*LZ_rYA+q6n4)7_sRm7ZDVh&{EE#AyJHD_gBB(yy75W@XEoy8C{JZhuAoa~&S$da zy8rPn+xtyUC7${BH^{@W!mlE6lp%C(jpm$^rqZmuL1S7@!n5b7EJg&J&qH-H(xVr_ z(@Uwh5NS1*$e)RzSxRbvME0)~f?7IZtO&`8LmUaZA%qc;Ct4MPTT@|B|*p4G~C0Rx{a>=#az@gp|(n&cmkZQF7%~KK$X5b&13^ zOPQ7y5Fg(WXUGcD|A)%K`X2``Dk%GZ>uCVP{~Jj4Qa8JCSa|GJhDHRsZbq+?Kb!`( zD!KtVoQz7}cqr|%X}1d4A*S9)mfPuA_9qd?Pd@QGVKBbg9^BsOzu4%Xan#xkqe@lt zX+u?1R=fkcOZ0AQc$v!^NnwfFFUE^6hxwc^;mf1&#$U2d>TR}Nkxmm+Hz5R2!Gz~I z?!X6h1@~4u9{o?$MAP_KO0C#c2_aor-f)!sPO2Z986Bml_4Mh?bCwE(EC; zsRvy^Ut*Tv$62%6YNmVW0XNH=dp)cYo=W?-O9xV21Ft1_nFHy{Cl6>8cBlkkQf{WE z5I8X7CFRo|6XM%nr>DrGDFv|Xbhf)REG`g4l4J4yBHToKaLHkd48l5EG^6cwvi!ro zK$UP+9377Kp(sl7Nj?v-7IjEsT_9)t;ESxq?r2|!=y;W(T#vkUGYmCEo{VOzBTnE& z9zA?*mgxI~j#0+ia^Z+~{Lgd#(?*JuHB1Z+lJX(Zie~}`v0Y*R?G^32ASAnXRl%Gg z{2CYBQ;CqM@^g;SCsjZV5@=+Afnq`X%dQLuG?0ZRk3KhGnNto>v_>~|^MbdyRU;Ja zR_x7MP-2edj$?kd6Sb_+_a)7JIKWu?Og#_!kPUmK#^02z0$1yR;wC%)dT?O5tIRx=L-6~uzBvz*kpNSf+ibkIj_$9V za!5j{&R)}It+qrY3=WiffS~Q3^glpM^Ts&PV%(BPETP9%j(Y z&X5f+JACeXYQ9opFbQoD0NNQ^q5TviCYixVL6__9m3+Ze78Ka=nZxx6wndJ5xvQte z80~r<4UdBCC)Qp%h!z5eCGzV9UD(&Rd^2*}^t9n&qK&7V8zCKpx<9^xdf#`HIXBp( z?vX@HCh9kU_=gzGnR&E7I1v+LK-2EEA;T)aPnAMfnG&AQkY!i+q0HLJ81pu%o!E?J zI{`fve94~IYmFKw!(`|5*9P+uDFQ0VKh>uI*_i>~s4eOz@vl`zq8aZ{IqZ-O93-er zvqh9)Es(dpmSyT|KEhu$A%nT z?nn#LK-~_KXAxW6V_*Lc7vSoG{{=H2k^!a-ou`qdunp@;d|EaF)u zOED0D@7k*XBnt0sfNwTt`%ZztKa;HAO0+xuR7P|KIVG7PU8Ht_Zi}ojK7BzomA>bo zEy)RT<8rPHH)aEr}+eaP8E~<6RdAG{3^&%pBX1jC#O$W-dOt z*%TWW9PeOsC=Flw*HyB+hT2)jj{f^a6*2LUqn>rItp}-+6f)v!YoJRsP_su^^e=tt_KWd2wTEEcB{H2Lx z_YB!^`N~oj)lO-LCRZgp(AuXEb_>ggn>PDQBVL$>AaCV%Bk8~PPb&#^8-clDA-NZG zM_;FHw8z{q)WTt|f}R<)NXm;zo1%KmCjw3a2`NUuBY2=5#!_V*`6fQ)QA)!Y3hBC; zY}<_S&fTp56lmTlj4y-|y*mlt*vMWe9+9N71$feQ_=4E}-@&;+%Ys~3%tzdYRr*nb zVUR1U?YLju15eb>56!`B3RPe#M2aY}Oex3pN76fnh9jB(JiVd*gm7FVF(fm9IxlVa z*2i4PS2v7_%lLHiXFyn_Ok~e6NN&huVo>8z-&l(R>bZ161&Ob{Di+vc1<%O3qLzm{ ztD@XSc_4P_=g9-N4E<0_lnW0$SA%g@afk<@9P zi|v3aa5Z)u9cr}{W?D@tlz3Ig34VU@d?b`~S{zaQ$U`x8eX&}xMRH0Ab3GP=w@#XK zY>-vH-!#f8VRq3`GK;=v7uhe;o3N3tRXZI(EWWPeT5D6oP347t5vEPc(v+MT`Bub=19excG-vr%hpbZcY-U83C784aJ z94-bePwN{AxM8ZVXvt80mrZXZ#UlPc-GI|Vgx}|p*+X)lbo4}Nlf{#U${kE8Ff%p) z^>pnw+ZFy3<2}ZSE#Lf1l+r|6aopMH9)Vm^|21)^$(bZzZsE|o05~tAs}|@Bp=Hv+ z!L<)|Yej;BvpR9#Pbm2>!m5g$*qD=X9MLilwPzw>MBze1V4?6nmjRgkQh*i@^;eAM z=?*W*oaSjBqVRq7nV_u38V^mUEi5X)8wR@HHx;N+5xUR7RPx>ide(3#hCFaXcW5-b zb8R`u{s~!hfV|r}%L@#8o7(@&9I8cgV>)1vY)OQ}k-Yjz{7T)sme4kSXSS#9bL_Yg6&7sNGMm-Rzcxrz{g;q%wbDMpHkAc(fF+vNUqHO@$4xTHaC{ z(W#KzKOeS-joU!FR~S>O;MeaPh5fK?^wSIbKq;q1q8Nv9 z+KG2?9B@;nn|f8Cta^=duvB!|<*a@pX`l(xBi=w(xj(<;?M5dMii}`u{u<6}EC3IG zyq$o*nih+DX-}7AZ*{DGxzYyQ_;PZKcHsRvrVJRX@aZ{xj1PRQnOIvmVr#tHx|&Ig z)5NZCiE5aRA~Iq=+tHv3H)|_$I2@1Ov{Bs*2WEp*v>!ft>xRKQz7_NzvEv>~+Vi)9 zws#b71751kx7B)9kB=s~ZZHlreM$Gnlrf+Ci1<1I@B$&{kcikIVnj-ll;=_7&kR%= z$bJ27o8HdrGkuhxL;jTV)q?mQQ-L$g}9yamr<%TK{S-ahIPz{MC8q+SXb>HunxZ zXz}In;qqkH`Q8jDbb=CIWfm#n8ngi=-eSYDyR=Q zshL`DCOwNth@tuNdff5Oko`1FE1Nom6Nj|4GYKo1w-N=g$8$eOx-(C0)t++%^W(0< z#=&0@catZBWfOZxnc7ctgqm+#iPe7Wch615Vg{Lt`i8K0dS{}s267F;+~y(Al_Wa2 z!7U92G7LAUS#}UxiSG&WEc(|A!WG(fKKjdF6+rLFXPLQeKLT_xA!rpw=K@+vom_HL zTN|F7mp1^R;9kglT+lLJ6B&Brtd~lNCCw8jECWy&u``DrRzu8Xi0xbG>hqJ{(GAQN zsi=hNBa1V4Q>=-0+f#w@5oog#%yL2@fN3{1PSV(Xujx9|Y_t#VMiAI;sn!Y+_aL(s zIf=Z^ykh7_MWl^+#QAY{BzVDFmd%g;+R8z@`6a+^y71SV`$q9g?o;wAbwb0U4c_eX zQJ&66PhC_}2iYhO$I9uJxvOwtz6CKuTBj^vFBI2343%@x>hiGdi=r5!*IfnV`uT?riW~&nVY1LGJPBd{vliHQ9VyUSqF+-HN$g`3AwBHIi8)P&%*v88hm7#{T zRn_zZ2c)0!9-#%dK?>_oTCl83HRZ*&(Ri*iCnC(6p>Ug6g0ho5%*g-dK#GR3uGTS=Nt0W7ovHf#dkc)`^Fpux?e#3Yj7+EAMVf40BF&&Z(mMC%XG@$Vn5_Go@$?hS+%8UFTpxf zBDFP@`mo)q3)He)z63h>sCpp4oai`WrsEFOQvfFD+P}d*)b2U!>IJH~pVKAaRyE+q zfIPDutQ3DP`cB?S@4`-nbl*7w0`ACElZWqWN01Vn`En;U&{{7)$*xXXebS5~PZ z?}a>~FN}Y5Pu?vYwf5s^RsXVFI^4A>4aB5RuC&_;b3o8}I@VeXb!T`01~}+LbM_gf zK4EeDA~U@FWCUqJD-K8trHnj;|BJ0}4zBFm){Q#0ZQHhOTOD@Hj&^L@wr$%<$7aX2 zlb7E)_r7=Q-Sgk9RdZGCRjbz62MpeqH5V^jk;PJchqtT_ru5(i`=$uTk84wzq+6%{&H)P73n3>P2F)@ z2ia+iEL4;P{sLN4m7D~LXeR3h46Xcluu#bS!^dj6d0zsU(Z;Xp&#(3V>AiWksQ#oc z7<7?tVlpO?34`z!X}c~(S|_d-EQuIIR}=4?7Ip0}O$%imr61$2WG@4y9e^4A>DETG zvrxlMatSta&UBb?nV;@ZJnpSu1QK3ha05N=P<4lt0*#5z+jF^bkX=v!sQf*ArGRa< zkU|z@>7?kwZnPG*Y7W*XJtjYY+}#1nd6cRci%K9f!x6C+97GQ<;ne_ScM_}jRaM}4 z@2H{kps?sV&)U(F=g89OP=u1)k_+x?UR^2Yo~8Df8r5zc!CaG%Odod0R_Dp{iy^>Q zuhUK<;nPfhplPeb2NtLVpikf~X%x9DC{;(}b;m8Jkh|viI0paAiW&l=m|AY!Kq^W3 zRFf|1fw@v0UA=3oaSh6hu$AOHcwAn%K2)^s&Jny|pAeXIM*Kf%X zpDY4BKfNn{!a_a27OSI!5d^H4wc%nLmVr2?zZpMKJ_O+(5rS{pTQ=JrSw;4jqvbi7eO;`dL0 z$`yJIM}!84?M@)2X(Crf)c7rEQoKdy`Pty*R|m;o3l4H}kk>AfqB* zRzm4|8}wwECV3nzMqR;WlhPCCNf-V;OjZUDdtHevS_dRyS6PNpjz@5gT}~mi{eC7a z_=|3W&DI-5f^*p9>Md#yl;?ojZiaptf686s;>D1ntbTQs9v1A{J+Fb;wouicctcr1 z%^a)+`IWOt9WVOfA$>l1>CeSm#R=iFp&d$DT!p6nRdZ)8#>>A9KMovPun z$N&gpQ3x<1xS!Fv67kY7EsLc(#7er5A^JC0nK5nzls@Hx6(fB1Xz!^F@9UuNS-qq@DY~FBQBLWskizB}x*rLp7y?62O=wSI&~Imrzn+`zODQ-Hcc%2{ z;9zf|$TQ$Vb;t9z8sixBn~p~CP+ZF|5V>IZb5H#wx<2-#D49?!m zZw#6g2DE}jHlHtYoO^3I*Z{==Lq;YOp_Y8jc}Cx^YB|H&+O?y@A*pfazb%vn=m}E8 zh^X$Du}tOxB(ufcc)He@@M7_NP4|GMJp+B*uJ}~X-!{e5oZlogFqA=XY>t4}5iPTa zjoQeWZ0dei^@i5FMA?(RgxJ)xUjgkq~I3=9r!@F>{tR+WXM8S*7cn|D1 zPluc+W{mRpXIrzh@tBAd8<_5qqbG6QzS-ECRFS;6?Z=`_RU!0LJwv92v`Gh6fxM85_wlGSURG$dae!wygAMuHz!S}r+;;%?IO$v zcbwSyqHUm4*GQmQ?zesTu9_#orBWbywm&|&<89)`T+m+PMRMgHl>QGyb=^s+OG7_oTn;Ok;;~N)r-juYp4+nq{g{D#OAfj0Gz^5V!f=Udl@Q z>x~{tnFvd}=%+&B9qwqc#!Q+) zVT9qTKNC&FP@&^jLt?;!uHURhYt30-OR|#)>DhQq?tLELB3bq0t6Sn-JF9*v`-hce z76_eVh&8cIn((P=%0P*~+S^~RDyZP>n@KIRl0m~X7|c)pWvgDw!_e?|OQxk-)Pz)m ztMxPQx&`S6D8IArp|YelA2v+ouv0<|dw$ZMoye5e-lR8HPBZM$K3fm6mS{TFu=&V= zS(5+Gk^;dgTH{h`pAv^v^7~apCj;N(1w9CavC-!hbBi zw66m9$IC1tEu5Ikc9Djg4SCGh3)xF&T7?UbFtr(iV?i`Y6hDdbeA*}P?a|kFA?6+2 zj@XJvve%s;_nCaTo=)!Y5*p&A6ITHSc-(w4Z(rzaZLWz#`dNvTS|YUsR;RGXW7ZNw z)j$~m4Dw@5cj=oUf=o!!mEnr+4lk64InFFFPsRP#|$%& zPVFwG*G(DL=~Gi%qIrWa5*miGiFK5;*Q{>f?tjQ1noHzmCRSF^D!kwF)Hw0&6E5uMPrA`HNI-u%rMkblS_ae7p9J6Cjz>_G} zbcR5F@GG$dG%ba&>M@bp8WRNdc9g#Uu*K1Xw4lNw7v}>xF|khP?k=uFS!69IEuPD~ zeRc27O`KldF1@kKcTBnvm%-4`Y$!Peyd!Wz&>U0$ntl1;Tp9ZOoZF~iIH6x%$T8$8 zf;2=MNlqqsx*V1FKvpc_g>n{XXYIY+KyT5)zN~}OnQ?xE6<84&PRo4n`aJt0_l27F zWtHnwOf?#1Fu9ZQv{s=!5i+$#K!ivQzCf86nyvW)Do}nP`yW-|pXI;#KkWbVUxs7) zfBws?EGc=Wz*K-mO&L2Jj(@cD*DLz1f9>&2jlf1h#X%bdV+#d!1|UY1Pzu6KN15Z_ z-+UVUGOWk~aGF962_0OY)^|A+;wz|vP+1Rp`4vm~6Jy6D;I+IH1$(6q1dDdtgN;#H zOM0y^onlR4rceVv+JVkUAjpO&g%%~?lD!%Y&rRUey#c@SxZ$1DN0i{{PK3jRop6(8 zaV2&V#B&8P6@u$%h}-pqm>f`wHB!emcZk441Er5tuDYQyK)654oHtn8%#os#1^4mC6! z2FqUs%^whuRgMbjUd>2AuKBCbiOXH7n+iKi-w-PowdjYpD*|^rcf-s31l4n&&WI> z8#S#`A-TKRR6#=p;2zKmD|Ai@4D7(*$o>u9Vs(HRaeSMgpNwmspgqeC`Tj?cI@F{s zIk`Bmp0BV&jxP%gZy{QGk&s1p!BEio*eM9Bjw^7wTyL9D1Dn0=tZp1?I46-%CU4;3 zZ`dzsVc01cqJf0q^uA1b!iz9n!L5Y$ULk2mAwqlY%*=o2p0a{`K}SZ<4=vlEy5g(( zL;z6rmaDBS27KOD1PFp5@VEBXbd!ND`f7_w!}Xz`QGu@~yV_BKjF-Lg%M~`9Tu=jL zDahIb&;4Z{H-9@|ZsXfK1d)g=`3*u-EIK-_`>Wg-dFy88O^SC{&AeZX+u+QN+#mn4 z!ZM@~wCvg;GYIH0-0bX4IWqBr=N(vi1^~>MsP$oIQaH}mrw(q-&I$Iba#Ct)=<%xr zf*a}>{F~XhM_4g%I&nJjai50JwqSc&i6KxT)SmR3BS`Ehl&miHDa9JFUXjIAB@xK; z>+%FWTKyyU*K(Q(_d6M!9kgRl)<*J(%M_DP3$NpMGRB^O#qG@^puTmhzw zqwJs~Y|u{^L+ua(ZbnJ@-aIavbNYD7e9iD>QxyYvnJvd_LxxCUQdKb~(JzWf@(yW# z7@8smf@vJBym8lF`t+HH^0MB>mj~+9?=$(U7yPpm-dg*a4)}ZGtz|>PjlyLpPd^*M zIG(aLz?^(|*alo`%x0sbE3uk?vjG|cMDW?7$t*EON<%zKZOJ*yHGdVt1e_UXJuZAX zl!`tHlX?9r6+H}+Hl5q@t!RrFSfxH3*2Be-KuJRjzyn;mdzd+Y24Eihz}}x3GxF+I zEqw!Z{QS&_oIL)RpSTpL;_t@pja!}iw&I&7Ue6Bh+`Pj-Ujujg$1a;@)n{f2-hk>s@wt&aDAEkS zyBSy(Ln)G}Tncp(g0&|(hsXwvMSl2oBg>|U0Q&oOeprb!X>XQPdoYHLAv9Wuus1VQ z+@Oa0DaxU}Jn8IyWOfs8*FdrGby(b{<82VnR`t4~Ns04|%gyPF#4|uwi}hPh>{_RS zWb%BY?)s#Hq|NPE2>}tH?a={iv!;>$a;rUUXJvVVzFafnUcnUrY={)KpK`?lOaaEk z#PV-Ls zQo|i;X&5BGq&B^s<=t><8ysry%x)Z;+#OCJ?an zk(J+mTcTW6Fxxt+9ZQz{bTI1nEMZ1l9N$m`pt|R%+hNpbL;%piA`L@Q<*?#4xgENn zuc3ILyuOzDMiD@dsxy*!WWnsGGM^%P&{w!a-=d-CoLEsQ13yUnAm8RVJ+n>)md>d-c-bOT!wqTQMPElFwk3 zGN`YQqF?urt_9TNN$P5Rx86WZ=Ano;h|xm6s)WH~VAUT|zQC(S2#Hot#-(rf$si^i z)A{Y$D_OCK4)Wj@Zkk?&s=xl6xLSq)%rIDJ{R%DP&~cmyexhG(>+7ZWO;kn-#OxE~ zwiIIGA_NY_U=wUnZK~q$+A1mF|L}sn-kRZXefX&29>)B32HeGWsahMtQ6wC=42r6r z$)(!DF@KS>PLxHOLC>rIB#Ql`IS3wkb%E2uo5huI}Dl8YKhQ&fOTHY@dDmVdxIr=BB0 zA(L{7kvW{jtlq;NXLS5@;vo}w9vB&V&yG_fWF{CtTt-(C7vk5$3Q>XpAn7I?vdfqt zCT7*nqimoeTG<5KD4jy1-|4M@+)nmXJ(Y*ohXrLo3)j&s|NIFqr<9VU9@YdyRzGDP zDHLT5hgbVWAjP?rJ#i@uPALP92b4v0pf5kGlFwF+|L43HNyI9~_{qov2PG{K6A9oy z_EC#(*H3$bP%>W^dJ+BvcoOTZf6cO5UwQeGbFo>M#H{H#rVf8lWh*1{*T+8&yMlC!U-lL#%wg14Y65sT3^CGo}rmZsV=vhAYK(KlX<)2 zA5)k+r8MH%2X)E%%h24V*w*4z_fbAx@R^g;X6ps>E180OYB6CAke6&QMDD3A(*1+J z%0+ch!87>Rcd};F@2`nJnGB@Hzqk(wMu+@K##Uc)-~;q>CTE83n6IB#c}(S~%>+Dh zyeNRCP>CKlG*b?}CUq@-*gZTh`ijPKQrRR$KS_rW+%j7-zj+Xz^ax<`e4u?zzCQnt zZt}aCg!reM^u&ng1kr+)|Er<3?nSQG>v6|%bYUfpFvH=>e<2h0U3f)Ajuf1b~O?P@_Z-}S|DdA zr*`!$1cN~p4PK4&!Au%-msr}lqaLe6Lh=xd=asZMH=w$y%aHS4fNp!*M{D{sQ|Ve1 zQEVI&u9g^@?B#rb!e8C~i;g%|g6Op(E2%&**nWEUZS{&}PZ6J|<@m={UWx9mAY>tB zUm#7yCr1u4L-n36M|-)BVOCH|O8lcf25_-zf5Kx|qh^X3`!l3RLh2xJ-ezHpC?b#4 zBZb4HC17RB?;cAB*f!=<7kQ6NOLrNfQU%+H==G55uPWjdiOF1aCK^kl`gv{O52=X8 z*1BbfLNAWk{8{5hHCNhW>jduC+dw>Ulp7Hgsz5H4F@k85+k-P_`sj8Te z0pcYECH3E#azeaC)*8Sq4oSnyY0VmG^tS0!V?L{(@62aZF=xd(AxF?@9kKJ}t1c&> zNSwGcryaz<^+)m}Ud{~L=&<(4eddBvAnLcdKSEGp2c7AKB0$+DflC+YLK*MjDAFq# zdH_i3(zuFC{EB`gX!2wphM~~3kT@2{-X|bExam8Y%D6&zwSsSZAf-{no9VrHuaBQY zVijc&YB!;S{@l{?AyQl%r4a0tKH35P192}B9uR$zfo3N8Ae`VkHU1C@85$_)eTQMQ zd{MuCKS#P7M6*s484-sCsfuj5>Jq4N?gKdUV}?*Ym{odhfZkexRj3oD^6@JMT_z%3 zTj}H!+{U};H+N#(t}qyMe{|}s2t8Gnv?PZ-)f-O(!Q)Xy2{~G(yWFu*$<cZLA9>>es#E5^a4oU zx@v7U#P?<6zF@?n)%`ALk_ESAlDe`ci* z)y!aDCs+V^I>V)+kJPfuV+2I2JphI(KFqh>4aVxi`%8`%m^!5mi^<)MRLUw?U;NxD z-V95TxNNuE-}Eim%PK}MH^gQszBDPiZ9;?i1$Z&PDMacd0!+xP7L4;i49{# zM!bWtg6*;H&^;<5lIY`ATObvIcw<(&dBCkA&+PK`9;N?BS%CU4kjcTCV1$AK%Jr=^ zxv`)H*sU|db{}aR9|J`dhmfs~{IrHZU8$9@wNYwqp2NH&X-I$y7YFOgn8ZlXpx_lGf+tI`s1pq*I)GR~;L;{No}5VdSyUjZF^{F< z_tYH8(MB(8I#hjzv!=ukLx!%*g|P8zTE>*ty&x7ZE=B?;T-lKgZHUl} zo`WK^kxQQp5@N+cPM3U;9ah@wKRYdYPn2txo5EJCjN4D##C#(?V($co4yaAyA>d68_^9Ep`5syJEbC_sxyqk@XXs z(&e`Wl(0zkKGBw+@inMm8xy@swrFOukmD)4CZqScqOa5WrF=Iz%a2^+xV2Z?*(=k$ zH2XCoU!KQPn7{*|t0Q)-RnIJQR=jAqX%R0`fA(Q%2~ox2Sx?-uM9I0SDtMUzo}oz4 zwBD~rSgr)9sOLq$3?Io2wsq;RShSQXpD_~_F%wpw3k8`1`k6*reMW=ZJ>GlJ}~oQ~EDkU@D!g9XwsXIEuoZ65jC^*V-BU$z*rct_-~>ge~tT~iNu&JIK;iLM_Mtj`zd_=nNIq!;lGH=9jS$4?|MQl zMWi9iwl;aiafW6(>f_{Z;&~K_;`V~$4^!!h%-{Y@liJ1B6Yod(Mo}?~j3pLT(EqU%(#>Aet{8T%% zHAJ$REU%o?rr?RA4!>gDvsb;ze8=8m0|Jtb?zUR-gxF*0oh7=0h%%G+x|*Wa&bUwu z?e_&X(chq*q-WlV>6B$BN$Y@@YJVaVDFA?YjS2txA0O<0f3Iu_Lf;-f%$#ih_@ex` z{jZthurLtfj0n6-mT7!iu}!{Ce3&J2JQtc&N@09?Pq&PJykz*&K=Vf9egve{AV2^4 zWeZR(i_qgdFi;=Le2?ETnyiL}j~GLB7jV`7Edo^v`JBr&dotd9REJ>^Jlig02S zlo0k(UH1KH4KqT2y{0Ez@H)U@gV&nk^bhMy{GmW?2wb(Bj2ne3D)NpaMA3Hn0hFVr z@7&)Z`dBWJz)%}T?n@;BpfvuRC3$fDnhsGxIDe?pz+`qsqZ zit^#Y;YPKkQ8HpX9I#6o$RUs9onAT{Cp?Eb1S zhIT83tP}LjJ76kU%O*fIs*)nOonwpxht39ks0n|5hA<$dwW+)Io9pG@Q3zsVMGwzj zPxkOZ+!lPk1+MrksqDzOibyC<;E@5p?);1sZj1$S*IKHRQLy^gka<-NVeHe3u!~YH zW=Q1rlUMX=C$ITr2Pc1@=?!38s4@x7m9@gAPHk)0 z5=H7UO*Dt8*oKnBbR$SyNGI$76kR~~V26=2o=7^zO8gQ=o}vgJjsOHM#0+7iL{E-8 znhKVO;6oDVPXMq7B(?V?kuXuw5c-(qd|Y8PE9}Lt0*qj-0CBc@3BN_kj5YHBgxg_d zE9! z7&>^BP}YZP$R!bTswmVuHOb_oGmqKiu8$4Qo64PXJ-|hx7!#)(jv2Fw;=;8@-FvCs z#-4Vbq9VD7d0h{|_Qoq8hf0^~G7k?PZTu$uebp(S=5AdSoZjA-2-$A|BUcE=F*m^RuQ=e*A1uJ-Ox@FZX$yN zCn(|yGPGQ~j<5<+RF}Mtp1W%4eM4LK4Q{7Ghsh85dYkiYbSFtYhwGm=k813phNwt$ zrct7(+6+Qvo|c9gxM{4BHfMXa;XNE`{wLAihRaw2?7IN(|4=E}|K&c*#LV?C2dN>= zb=&oSoxvRc0k=xli1XSY&G-R*UiF}(Op6&NA9T8xbWC^qBomfMJXUXo%n8fB?z``+0$fVkM-Gpltkp@^6zyCe}FP zY?~+*{+{)ARUqF~-uUL{r|G=~@X~y5*Lv>|T!Mm)WswFB;SH@H8ZgHkeEdQH1``e6 z(P5#1v7kJ6!}ijC@AAbbJO};R2!YB39%u+GfhgFIw}WkRTE407)r&Q7AE*n}PaBfh34%ccd9@rGv_vQ{e)+%Pg&?CZ{O@kOUdFpW&?^ zWYQEt*c{a<3z-hbK~H`lRk$^O(kUv#dG~R<0_U(q@~#5kg|Hsv+!0*^hKS#RvGDL< zdL>9ApJ|Jx0NFz|^n%vQXVFAGLA?T#WF46x2^4MmBSEfZ)cjuasW?pRv|z)hWuTgE zt)RGvwNWWaT}2!`d85rORJ~sLTG=IF?+mi`2caSUtK=Zz;P=uzdZBJ2dXjJUJmB zV{$p5$8(gjA2dC~UxVAje?;LgiDIJMgS{r6cbnk13*(!Y;KxS>n8CLOFSZ<0qHe^10UMnT+)2Qi?gQE~O;Z!&*y$+{IO@odnGsNhbTmsfJ%#0Ex) z4y!MFI6Wx;Lu`;)PkQG=lXNk6rfwC8kcsV9UV7dh?d{U`aS&r%a(5Xzx2&hby}P(j zHzQf(G74Pe^?jrVz*;+D;>>KFLD@e*&W;nVDm)c27j$%>{0ZTT2nq|&wutMuMAxM3 z9fcSh*_Hw>T^{6#xQyg&S|leq%lNnFbY3WldR{zb5w|H4B(R^LXldxc3a=|po1j7l zmd+k2yM(?2bzuLc3?);CUTrTWI_1^p6Dal+QcHrO+hmM(o_B-1*^p3_FF4wbeT!oO5{bt(wuuF@= zcfICA{kgVOK(O4rigCG9xbGBb*z=g!4kSS;D5V0Y%COD(Lc9V)3nVah<&4{#4~=_? zRj>%B3Ul`iK$W8qLQkh@UdgzKEIR!x#i7KmqAT|NUEW~Q^g5OZGB)vOVNC`reX;{Q ziA2=f#v`)Rn|Z=IUcu$9!G^DHm3?~EB#6UZljZmwFolZZ2jo{7(H7xsJby`phX86F ze#nTS|Ai&0SB|~gg8#$Gfj#%Qj*)?j!OCwXhqoKN(VQDzq5DT>XLjMrI7rS`W!ye{ z@WBN}6Uzl18N{RJNNe|@Z_P69qtLf`-NLr&@JGcY)A1Lu2N=BC|6h;5zE5B{{()L8 zMa;lL!1(*ej(<6TN+O#7|Be6bV^0BN1r`Kw*$ptl2DyDeMg7rExP4dGvEQ&<*x@iljI7sf!}bb9yVyI- z6qYqt&#SvXnDufiBj~RcxK|LhZp#)oYEHv)03eOLe-ZiuMuTk^gCcG(U~WS z7ZP}HaGWR)&W_B%?nX!nt#>{T;5nI{8yG(;hX03$<@^s8vn*^ZgoK0%_ZH-UrbHP9 z5GK^1rw=qYsIacamaD4WJkh?9R0~L$e&2K;arRGd9#k}YOcU~7#T-+7M_%5tKX?Ot z@lhc5e-CTx9SB*et|6N`DJ~IPLM?$glM+oBEwug~rw?`hK8H_zKI*qd5j+IN>j1^83D>Q~I|zgGT_7a4i_3EX4JW2N#a6E(#8z z74kS!DjkqZYgj5MX9zi|;bDNz{`}P92*H3s!^{i}Lp5DKsi*^6ic*u4!sC~w!?_B&ZEL>*1;b!ME z))Tr7-soUdY(Q`*7O~WbQ0;*+uFRG0PTcPm~JOX15gM2*5$nRyP}D^C!G@qF63B zac2e^b(wJo)i5*Otk=AQb@a8@Hl6S<9nxfy2ghXu5imHUP*rX_i9fAOm^9*TfS@Cp zf_p4Sv#f4cbqqOV8qNn)}ZSRy(P27Fpo!wa9%oX0ORM zEpDwgQKk+>{rB#nh|FdpSn(q-?Fsf&^{}Qc*0sdgBsw#OA?>sE8d3DzOnA-dau{G= zU=HQLI`}T4A&M-U`zF_JzPqg%NtMz;!(gP;0lxA$BX~tu@EVH@H@+0AjVJ)!js3 zqvWW$?-R7$s-bJmv9&V_Xqvg!{R(vz{G~d>=2F2~7%39C1 zMD)0S%hY(-&T6W!V(mZnDtcVNv5>k2fNjg_b@eQJntKw8AkbC6MJmbh+ad7fn9GJ9uL zj9t~-u{*vN{{`#u1$d!sN!22eC98WEKMioUYys=?X|@`u&fLO)6mrCgGtS z@L5?P5GdS32&FsM!2??r7!2xXc5`9@J^-?h*rl)6CjcYxdofq@{6UEUz`NmfFM`71 z5UVkoy*%daKx$7F)Pq6mSGZN0>Bh*F=p6eSJ4;x@2)mt|F@-HT@^8y?KU4Xa6#};R$>kxFyqB|VfyGQ6N5DoH;E-K=J z%?y8I9J7)3N4e$*kx|v@`_PI<2WX51>AO~Gtyr}qdo>-`>}3Q?Mv3F;Jxzsljd1h+ z;p_p265WYTz0h8Y9*#rTfpa4u06m`5IRw+lMT4>J$HBn?x+;c>3yj`lab|YSQVsuy zJKx9W$lJtM^^$>2jnA5{+`_@sYsbU(vVpig%W zz200{4{F+g4(~2G`w;{Fy{V`5iJqU;x66#dkRlBt3WA{xV5zZ>BU##>tA#?^j9S7DF&0aP&57ZWA<&%5H z86Ho+H%!*=sR(#&9z(QzT9|1wZ!Z`RT2NHF$GQ>D2NUf&$|&hk0sQm&<_s-(w9BWf z6N@hg{OyTOO>R81TMrG5fZ3WgImsa=0Crbo-0-MLBGZ!Cn@&WgdWqv2aeth)8jt+f zv0ahC+IIKb!9~c~lv;Dh)Wwym2w6+3b19j^lMx&V{AW2?$8v$ytiP4>RCquFall9v z8U|``v@mft4?#;X;2qdXaRTX=o0a{Xw7T9CeY!?z=M8L^-)x3{ z=VnhY=nkhOP5v^C zW1eBUMA}5Mixcec6!b|1*sTnYWW~<^YaIhl0LPE*#ry1jeY3OQHxgjC(ZGq&?QrOd z|9#Q)dTb}5k0L+;JO`E^%ZvG67jTX!Y65EDySblFcPjq95Qk||{4g!RC1A?;0Wj+h zNUGNrmgbPhm67X4MWq}E0@@Ko&g z^kNhI8FWLNtCE{{F{!5az*Jo+)z-13?MsW0u_D6S}3SQ8L%+C=}2|+2SHD)fkeky3NPO- zLPjs6`f)FE!@(X2RadqB=uaQqS=3c7xA)#|^g}_Rq*|sx^on1~uREv`XlJ2*Hn&C5 z$m#k(Wq(G#W})9&GMwokMCU)O63A>5i8J}4HHF=OyAA%uCFr%=RN4do3wpI zc*`U+dwUXJbQFGWpFxi`C7SmrdxD%$KbS%|f%?^H1nV|(#4(Z|0p z(>QU?q5%^R4vo(^jLZb2YXjR9IMY?f3nZ9mk07XYZ${$W-VNazu%{UToxlW+0{mYY zQQsKiAD{Ql44vPY1hq)}9VmV%(EIBvk!BHtQCR3YExz{rq z;AoqEF?Pp1Z%Ibcz$;y6=V_$i9ehFitvAk#t{g;o-HE0;xMHUr!yQFir4-*X1lv~_ zKsRbOLvjF-t2+R9Y6%8uSpOX}=xWYdgBWp3x)4CIvKL@Cuh7+Cc_o1`79!|72au+N z;5KYN-t-FSO<5KIwm?b==!sW?5wxL?0dBqg*b3AR>XZDRr_QNCKkWuLf7hWw}8_ z8h{n}q#ml4K4r)5Hg}gTP!5qv!<@Af?=((B&HF@HlK=t9OWG3rB8m9uyFK?8caGlL zo@g-?<#q*V8mt!TYBTRed*MgVo2brK*;5R1v`+O_JGtok#4H64|_wc-Mc zygg@(2lfbb1(`Z+sIR3b<151U-zb%*TIot-E;i;LJGdCr{%uJqd!{mwf3$@1?FEg# zj)3aAHL0<*wM8YP4(?KImgGkO*xhaejyL3RIwe z5~GM`o_PyzQFQ!Y;TysFgtF z$^x4T;wjLC^iLax>mgS;UoCf_um&W_76}NR)Wit~CvrWyz|Kb$lH3lF7TsIK8u7q$F8- z7CrKr1^46rDI;zHx!{n|?FW3pcvBfvnq{4fQq@M&*`>k6%yg_YeDhU7)IK2@catZO zYM~l1`?1a%Be3uH!>hWQnct&adYTKEG%CQ0sQzl%z)|~DcJ18QIncSFZvoJEz29qj z#;~@uN-$ToO8*)ZdL2wu-bf2kJmz?x_^aJ^6RZBderFwTHzmSm`dS?7jE+yq`c z(=R(iPU4&bcU0o>tqgfQFGhe~*;YVZ67$K~W4N{amW#d)l|hObPRL^CCr-EV68$nr zecQNPgPBiWi1(@PsJj>G`c2s6^~^N)GNM3x5s+!<4R{pX!}#};q)O!#&kJvpUjDA0(R)~nm8tob?d$A1OXk*sq&k{f-(XSB#1R~xln!Uq7 zn@ZZpK6e{BhNj1hSKP~CY|MzC&0@LsKV9Vroty*YwM4E&9ZG9EsgptS>ZRXo45f#& zKNn@Ip0E*;4s8%=Qijiq$$7Q0BTMx=6ZYlrJjnUC>KKoXeP47Bl}pn1g5qUCu6!0Z zmyy;0WX0UuN;=ZFXT4|I3O-Jg0E}2AnDsS-AGGh$#6#$7=TCKm13+rawIo+E)t|_( zmIl@cQu*(o5SO>D{~LvIva$XH!pKv)RDj`ung7u&&;Y)1SPN3uOwA5co4uwQZTt^N z@Lw>}Af&#AXFH;^LU9;=NG8j(5IgU0oy!ARdISq|c`3d>r>E;9VuoJb)u!4v77q1*vck2;hYSe`Z(w;2{ikC*#l!hZ5{aW z$4qx_wBxZ{*~&>P(45N2@BFwH<6ZiSt>l8gvcz4^o1GkG)Sw@uAj;LJvC6bZ`}uy;xbBg6;Q%O}0^4F?e>N%C!o)0qW#GWItMPA< zHp!jIsW_FIvIeY`xxHKS0TukV%KKoom+s=Ecv{H&?S)yEaVt`&Uj`?5!e1K^ZE^;} zrKfUqD9(XP+Vtn93X*kL&dR1lNKEqx_uXkXQwS^*(j`^QO}p-+xGlRN5_-Eb|*k@ zr|n?srRJz7s|P^0j!<%kz;VT2yu6pb>uk?EvHn_RwkwTktv30_&gYptEl_-Ca0$@g zEV{e9FWKJuJOb}|cX~a{K>6eW5{=S5ZGMqWNKtpZ4z(I%yuw4g;6z-j;|z$0{Z@)# z#)GOyG>mPnW6N2j$Swz-9D+0~8ENrEH60XtreB+|0q+N>m>JRHr8oV#uo92eDuH~3 zS_&pmhKmkGPw%Ll>&FzFMHFN4#{tZN|3dO}OWfELKoEL$K-BdVw-pKR4Heu$$GQPe zGwzjoI}$481%`a8l$6#$tomumgVcX7h`7fUd)%qb9;oMUoNQl%<=_@2*RFXPBnlxP zzHxk-Cbdk1JBSffwuXd+NMmg{xaYzd4Vq2~gyC|;`C6AQ=s2`D3&sW_hYBzq#EuuL zTH-7vvX0$TlXwKGs3o5TVgieektopTbqtVYAml@cYN2&fUQsUVE}c7tSFS8gGR zz)n@KLJMJbr4`QJVH7n?zO~2HX69VRjwsc00=)s1kZ2xcf;FW@zVmlKX&&W(mIb1n z1up=V1L2?Zh1z8vE|(0V{Q)5U35i~5sGEnGh*@fk$op&2QkQtq44TsVk|b$2vDa-m zGuV#{%$NKZsK3soy9p(-OcR5L6ht?~ci?46up1ro`QvLo%^O%8c zQuE;5O+>|+S4rHW4o~I1jNWQwK^J9QOH$E;Oh65`C-Gph9&aJylFzP=Je2=e=Jf10 zGK@MAhC2Kf28I6l_sLmnwdgMnVge9+zts;LXP3kQbL@P-JFT`C;6;MP6&_~$;JO@G zKOeMR$7*UUV^C-Zc|9XNK+<#6N+!ITd)|L-a}(S!5Iugod5&=L`E~m`cy|!P;{m%@ zeEW#(`pmc7x{wyo~*d_u@6_<8ft*0woY)CL8^uL0WW^$HM77Hyof z*sHukSMX3^a_}%3ryFPQrtD@cj^LR_^GK!}XYM8}7PWKiH&R#2xqFYCs_13kyd*3Z zw+rmwQ&%heC$y1r^Dlw3sGWH~irQY*-FO67A*$%~j0sWut+oiJWowtICpfXZcSkOWvJl|2Uyo<$o5- z3FazUa_$`a|D(|B81i(sF|PN!skHa>W<` zZZ9fR7FozV3PP5PbhZfs9KWxH;$f1r*9HD5gwtWVvxH*~kvFz-QvM}}c(o15?WyD} zF&Mf@uKUATlEFMXGf0TKBnlMPrRBVITgtiwX5`GePZZ;yFCVC9LfYd-Cmt-w1!ub* zKX9?|?4uqhL8_V}wrY7U%?ApVgpiY>4qv(7xj0Fu;M>E-=^2=7l#uBm8x4^gox(&Q zgv|wSujPdj$md5fBIGa!EjKhoG#0_`h_s`JrVl|ZSybU@X#w>NX1{8}@}i}MxOp8# zT2JALTH>)Z!(g-7BmO(856qEN?HCkP2^c9XJnwDLblP5xF_bdpMWpc{gK5267S2%Y zv|^`%G6#n|Z4(?K?K6_T zi}f_GmMz?11p2r3gF~5AV>T7ldnr&iY8=cfVPeZ_k9gwuEl}+c1p4l4&(p$u_kyjL zLQ98>=# zCA3^}b@xNa-H2R7{&k6ZlxvH;yOQ>o=;t39CH(fZ3GEbXBAa9l#nWFY;K1doZL&t} zP@C^jjJU2e*2ePI{@_U4&oH;h-)L_#-qyT&NKYX`&p9ECO_ee5NEn8`mmZ4Fb`kdX z6u5zjZqN@-=3nEW+r%CGy$lw;@9$s{;ylC?>FfPg-M=oa?j!BTrf%uSkx0@?)IC4z z_z}Bts*g-@QDPfUos*%HSKy9wGePsiCAy|-zwFq-b^V&0cbPf`bCn+a}pS6Lws zCiWCF1|3wp(sO@7g$higT~Jv}6qHMiwij&sIgW&;`-ntbM_4N8fzVG;ESz7!t%Ram zyPLQgo5wTZ0|Ps2YXd61p(+Ml={Ip5qiR1!Uk6ENXb++r!UpZ`mn3YxO#**tx5`@A zxGnY^N!`CRMxy}wK>hAb>)2OO##O^>lv$rHxNE#a*f)UQr?|KN=bNbE;5cC)Q-dw!rL^kua16DLN( zGa@^E>_UQt$pVE?&%ZrB+9j{`tz3oT=)QwRHai;n*Ike#Zwpq$@OujLLZu%+S#p=v zMr(yEgAt2QDx)7R0O{FYzjZP*a@C2)Un=07J)Pf3y$om(gUkylX z5qpv~-Ts2Sibr27%|TMcCJ{^V;8JbW2EC@pA^n_!I8+(t$tyhZ@Cdab&F zXpVgZ@h|%#GT*s(byoj1^f++V@oWA^oo}bpJGuzAq#|e*DU=7)r^|C%+Dw?oDsd{h zj|V>)<@s*Q<|YY7dyPmQIH|J_@wB{Wyt0fubBY3mbrdGv9X|d}m$hE@I|}F=wz8Lc zhaf{M5aaKdpSfnz1itUIG9UpHo2UeCN4%D1#mgp?KS(YeBXgT%pJE~Ke$jN|NqHE= z-Z!*D-Ml=Y@2#q}6}U<`$8vVKx;o>r7p_OIpv7#i6PEvJpN@z+>tkf;H_~9F@NiPnisK=TX{gPXxpA;7oKhN4HX+HbYnb!!WliAF!>OGjL(aPd*8p+T1vZTA`_P zHmi&EV`a0%xa9Fg2kiSxZoGYUt#0|;^jrrnM4u-~>gn#QsDz!uc*((!^NMowuBTQe zbN;lJY6MhxjoUKLdNFRvv(-fXfNExrTQ4n>R;00SS`Y-KNV3z0!6vh1j>mZ5vMeLp zQ2W;`-sJVd6hNvWDuD#Va|-;Z_*jCnUV%+&u)@#9^01 z=N)+Zah&Vn=rsJA|7M^KpG_#aS6AA(q{_=wyH=%gL+{GPdFT!Zvi^9mvt}gx+t!1o z4whEF$|_LQzS#q^SN4SXambuyTLr4)&)5YJTw~UUC98_tKzMYnZ7Yb+7h+WPEt?%m z3(Xne>_dys{Tiv4zFM6UFAP?ijca~W*W_U;SR>=L(PwVy(Y|b9)zqi?2?>(w-86eK zG*5g)o!i`K`;)}rl_-a1-hh*Uj~Yv)`m6ovWqgN}@-;b7raX{Eu(iH-Q(X}|oa>{> zK%gR!3jf1A;&`p^ko+e}lRYui>S`4cJL*4M%RCm#r4XY0Pl^;HmMahz`Ge%_~O;}IsJ9nR(PzeLMSAx-_ z-eS0B(FY%^bueo6gk2U#^W)~43Lnl3cUmSnZZmR*{t>l$4!;{(twZv{^l-*`R+2$%wBszzD&U9nJlSL2 zA*wOCgk64=D=t6KQ+RO~w|n&nn!8HL_an*)iHIOQh#gEGfMXPX2>=Jm~ef`y^c_X zjnU*uFcNKTRtj4;_1at3yFMmk6!t%k(>d)oH!t+x-zFbd4+VkGgU#kwbNfy2$GZ#F z0Osb!N5PFxm(Mp0TSB|XE&=b?&h{BQc3TbVvR(FH4st0qzTwAA7qd4z;;n${1@Qaz ze%0wS?+v&ZwEwvOdH%Q`uVD9d`3+ug)};YdW@Y85vFCSUyK*FwaZU?CAbcrPp*gY~ zt?NS{(UUYXabuzV$xl+ZTx&Ug%(HK=!_qb05Xb^ndrf#m9_1o8hR7>bYhTS7plLB1 z`<9QeRky19JuyxxdA1k*e3Se3G+-N7m|MfVc0=d5^ic1sY>gj-bO>l0hhA$s)vtqMGa z#6Y3_Cc!3;=6R~8L!sh@hW76?YGm@2JZEyYF(M7)B=CqttY;FTVYuL8;)Ax}gbP$G z3><+oozg?;hBV@=0Bc1$r(|dt>qKE)LZbG02faN8Nt+GOJ#0`|uX;mX1KNr!1A4XP z;GZR6_3B*Vf8<4lsJ>6+;Z`~>v%tJ)wDd6hSrF@%CS-@vVt=5%CLk&xY$$+cgFvWB z){P*tqi7jtBEb~R|6_$}mTv#29dUsOYN-!kOm-tk$Ghm2vQ#pUm%|d+eC#BSL*Y5-a}A z%|uErHzbv?j}!)VtjwGm>RzApDX$$z>OlM1y7lw?@{=lcf`S_Y-~IL$Nw8huUxyd) zdhkwhX=D0e+JwP zYr?M+X$|v^QZ{2hBrsmBP5-t1f~g+3tI3YA3D6iv&LetAS-~Q4<&ic}dV4ixx_k*B4@G5ouNHJXKjW z&+Amg9t1vt4$&YU2c@BW6C5PeK7Uo#N%h0T!AbH?IsT*)un$5Ptx=OK6KVfR`cunR zGc;SPbj3F;=|vip-rl{A$-5BV3s6&@g*zRm3sqkVtSFWKgg=H;Y{I_XN5n9;&K=Vq zYsOr+kmWIK{HT%I+|*eVcnxA$Gc-2}9*AUe6oF`r2n>T6=N!VMy;zzny(#ZXWut5A z1u|=>ZGrkb22E?kup{1Htwc_x77xu@I`>ue(=bj0+T+2nB7emLnr-?#A7p)xvXsJP zNTHp&kPE)I+^9WjxRO$`6XFgOe+7*@C5}_BtrP;BlI&iyC|C%FfeRH zpJ9qZa6*i)Ax=E-%TfNqYnur3f&M8+7lKSV1;S1oe`&2 z$VxDahysoDOp<)S#FeDWbxgXsk^}*z#2+Ulf-glHC1Ekn=%ijH?!k?$Gp=)bk=rvS zTKT-(o?$cr#ldjX?@BD;O*qS%` z-@g{L_^Z@i?=T$@()1}^jd|yQB@fo!3N;Bra0qPp00Tjx-)4lhC691;3;-&T z0aIR^?v0+5+wjE1B!_>J|5#28g{`;DXj$p(FIFqe>Y$DxVfA)|XG_WY=WF+*v( zuL-%RO!ay3#O**0+`GiO8T`4lPxhSDRXVgOI=>}u{w-DW=%K#KSLW!suj9;MqVJij z9Erc;wo9yHuQu854ip`Xne|JqjsDd>=|9!l>H1%pwa8y;ZR$H1R`z*)h?v^-g5x_U z{=xIULVP4*7M)c56c|!#3do zw}VG2hkYft_RwMSL_*7=r31v!@#2RU&=8$1AFx6ZEr?Hywv8ZjuKkXPcD%qZ1C&@+ z-xBeXDD}XpMlLs&Ufku)R~ZR7WuYkyH;2LTw7?CK9cBx!5cn!_qp=!_7(Hw#=kjd) z9}5#Qe}22#8(HvC`nAAz$Q1fx21oY;2S4AG2cc@W)>^sRPkh_%xD!ks_jd{mhMZC> z5t9f@&6tYuA}hQ9q=uzl&x(z~crjix>~~S={SFgLmcj7iMmsGM5;$!S=H#i-4O`=%s>qIf&S``VmKj9H1M4|tpF58dCgTC{IBBw2($GP=6Ri~}DJ$O`fGS$5?bND2|8Ylv)G&<^-+CoLzls6HXcA+w=# z#3pjcGd$%3Xx6Pwf7Uz7HT@#O#HF(Ean#I1cGyz)$2Wa){T@6(M4vlH z44&Ip+EmFmjmDgtzH(VGuO3n?MW@3pY7It-;4AI0eP`7QlR$)Dx%sI+wSw1jPTJjH zs{;*+8$sG@ZRTMxmstE4zE*45*j|9}khgFD_xFJxTQT(omuai6O!|Od*GF{j3wsbj zZm0+YGlnh8_s!8#=QWz2gYqL)E)csvrj&=G;=H(^hY~Rqb}g7YldI_$+Zhh7@Z^50 z7hV7CoJE;^*r25eWInh+nX*$8Dx)*_4VAQ?9q=spVh-|MB22m8F!t|xYL#bY>(N-U z4*~{T`~x;+*NQ!*`%EsNKJk2_>`nosYg0YGh7^FkAQV&ItOc-;{0LE4by{9PT#EF8 zn{EA+^c&yCc!|QSJ8>v9nbvWJg>ytVw)#9ku5Y*Gn*HPUq^4Ev8Y>c~FzrNvwmdLH zUI8(zlh@$_OD&PzqdF?7=K84SqJgGMU0wwdS_$!E<#Z-Qd$a{m>olurcK;eGH7fla z%GJaJ91HxL%xZVH+;6uHisz9nJiNjanl-a#OOII1n2`q$FCdhzp6d<|4;<@?whChY zM1q~aRn_U+>)i2ZAZ!(3_V>omYoe}O42JakY#!G)&QJF8G@gFN`-J;biAo0<=MmfG zP-T_v|8*6o#^x{;t#~IaMR%q_b!B->dJZA(Ixl<CQw5yzLI1j)Id?5RRG+CAutT5qlh!Z{)62m`={&4;gjNQKXzyay)55`6`jONAf~q$(v!Zo#GdVB5A?)C)#2T~ zZh4<(3!j?9h4X@f<21EX)!G=~=4+l_@G|||dGZ9;So#&Y=~$gAoI<)${7>$56LUyK z`A>erqJKBol03+v7y88DdsYiSMF%nquw*GCGlbJPBT)GN72 zL^=q(VKcOAX*{zr$gzo@Q(!d75lbIBey<&){`awvMQef`sw<|G|=yBVJc{GcQLi2BeiBZBn!*IFNGKGfw9u0v7TAqI!6ndP>5n`BOwMzKA?B}VYr0nnw zn7ta8=veAgtfxO-_wF;Mx6RVNJM8?Xs{fXR!txfL0 zS$C`Uhf=p-2y4Ay&|h*KJ^-x3^Wl0HZIT{W43Ax4`jSh)5frj>FW6jZFN(nQ;LBUO z=No_p#k<`*Wa1+8mN*pGQ?7BCnvsR&&ONI1sFHW7w4f5G3ZP{&N^ldNqP`}k&OqCv zT)WGInOsDq$9Ve&axK2xCcxn$U#x0#h<{s6y5YXM71$6zq3s#?tM0!;cc_~EK=5UULUN$1e-Fk@PA`W=f$-c@E<$Cfr;cY=mYtVdy*BIjAb?BIOD z)VRo^4Wl?V;C+suiOmZf1QLmun<5!>pJGP=j4@iORFs()eG0W)V;n^Og3ZMUy1BA>7~H+KDT*gsi%1!=XE>ReT`d`jFudadk*V=H@vek(LLGe}&8?K> z!TbKe@2v7h;>#`)YmX4lHIf7d$#>6z-W9_iRwyeO66_ep5ne!-OV4Ky=5JE#Q z(CV?>$$@>bqZ_cjai0cX{7d+ZwuP`o>$O9rdmguS@m@4RBu+z^e8b9WCJg<+muf4n zvZ!hR@^lWZQ;otFc&D@+Q_=gpE~(mU<#SX4p)31kSx%R0eEd!GUPMIg>CEW$@FPJZ zl=^c8c>E*@l|eQU4n;kGH^@Mz-RYn~%N=t_q!1%$p@Js{f<{(<4)dLUskvOv&; z$^f!yI?tPDdPw`eBM|X9Zcg0Ixp1b>n^gY%UWi%B5|Lt%(`ca|pk_k@t+iGW8k$5g zVSnWr@oSoD=Hvwt>Mx`OlqbqPBB>5b`86-SR;8nfcp*}BJ5Zvk)x$U!rB;Du>#Z4< zrvy7LF>N?HLdWAdIAmSRLz%U$EQ{r|XtZECP?@5j<;b`ITf(D9$y528k>j8abpY$? zB)`R_vvP8WC#+$9rwV-1Lb;v3nC&S~K_FlAI@e3$cBg(?+PZLlzkWeRMOQ74&Du-f zi!J->9hJ0|z@3&>L$rCf7jD2JsDwU4mG5d{U~#cz#le=oNe*or^eALm>BgP~uh2m%T>!Y0ZMXckx$8f9NmW1SQjDT+`6m z_!b0)97@TrHR3LFLF9oLdqX5a14~7u(&8_@e>$3AKui1-(~0TH2zdKeLn5?8|6L-q zF(y~?lNmj$>@_@>WAwyhQ2k+s*X9qQMRdLEX^c}0DeY|99l6EE(KyWIZD2cO)5M)Nk!z&zd#jq0Ik zWT@5^VCmAu15VX0oS747$2lJa@tDR;Ddtek9S?>yP*V+ks|QyURKd-kg5|GCujigR z6&W$vW;6l$%6V{ zF)we06@*{+YyhuK?KaAsCfhc+6jW$Fr*%MkI|8%Ly`}p@g-$0;vLL_LyCQ>rg5cZJ zc-JLoDnOU*=+4jzrv3 z|Lxo20?PN*2Y+JJpAu(o?0_*=IGdLUf}*q}YgHbI?ch_SEkZ zXj5f`n_ zF09zVjumfKjc6ZebNrEUnTHNPalroSbq2n|7%8)_xNmPsGksv&7LmK%8nLAGnDfv& zLSU|kn#d&nz&*X3frQ3kO&)4Zwowy2uH?j zh4It^flKj}=nY005*6J{?oHqX?A7AD-Sz1Fxu;x~{sKnbG#tA2*oq>|`j0a=ih@H; z6Ru!vRyE4Ghg)_6EcwG+a1fm4QxNgzEAwb00Z?{GXK`UMV0nHL;(UG@+L*j1z0noP z2;-2G22(CM$DlCV%f3$_lXLM*Cek^Fu^;k)bdK=lEuEwZ+mv(3kO~`mC zGF&C0T7_!qn}>xTq-l&k!LqlXIt$^lOD=|*gYE=MDHVa|&z&J3omCB6N?hTt7efg~ z@XTw1IIcR_Uq4T@8XB+>(%;&dZx zJ&wrkyI%-rR;HN*c8cn}GYg4u12?A?m>m%^d8+5vFm_;b@m6}J$Ft45uH#~)TxjCa zQo1lg?O#!Y-d`l93^+RCGy}l=1o|6*?DUlJ?mEe?eKGJ3$7Az-u|63`T>d7@Q$Y;7 z`v6ln?&51J3s(OSyl$3!(7+sw0l?e3F*_0E)}vjq)jQ%b`SciUNY46j3MR{jEq@|{ zcf=(iV0A1J%eKjxCo34!p32mmN;VX9MV>%d&-uPUkt`4~Sgujq2qsHD8yy~SmX$so zz~?T_$DU-TAot*lzjwyTqG-w$;Kj?4g|OAe<=gDm>U1OUq6&_L@&rr{>2ZQD-H-zJ zpDeJ|%WxE?OV%_5VIf9QAxne*;kLpmC?ZKHS~q{KRvxUExpq0t7`Nne~y5=%NC8aP6gwdk5$_R0jPo zN}HQAImZ{26rB5O?XJ`fiUGmF$-xotCq@ZWG#k4V>CRH%tx8a~8oAi4Hl5Qp*{-S; z8@t)89_JXZ9xOiIj*ao2J|8TOz3%FquBkT0@RUWbcvi~ESCoiQnpoM}P}tcYiVTWP z4k5%sui&)tj4rPZ&%my(rht9mEN=}Bi)V~Q>i9mm=1DM^t$`r0s`!?q!uqCu@9qZ% z1|TI7k!#(qT)?z6{(_XuC9s!t0mbi(qk_aB#*?4NU#{8j7KYF{Pp`XXX2zEW)@Fw{ zSUaB{`Qcyp56r+DAT}_Ahf+~l{TP-3DIwdN2SGJ+HItX%01;O=#?65h!n80lJG7BN zU}|;)TYB>ZWvXpvh5S%SV|~}BBL>WUQM#9V#vq>D(o;jiQu_oMw0r|nHGg-{M!lKP@8EaDL)iTG{WsDE#=mc@KI%{lyHn!VRu7#;5Z!Yzo*wF+uY1 zE@8WWjK5=z^}s$c;#5rt@kV?a3BftA)H6A;G%`E8e!$&gy=Gs$sb~6rR(g;^L*q^Y z=S`pLbDujPE{+`a%*7$bMjz?3{rmQIa5?yReS!fbrsj4?21akq>vQwlz{}cL#>f0u z7b&yg7e-i86;EDV1>e$CZU8T!y<>DU0i^7cH}UxMRqVq)_NhyJ>l4%cbF=?lA?l-9 z^zG9l>l00DZT_Fc#?Zqh$lI$w=v#;38EBm^aFOz^?8 zVt!eLBIb?gQf8WA{aA%@!G!imNu>ePm8Anckl+A3?-<+CGD}nA0fecEv+ATzD^lO+ zu()eMud*Z|H0w4XZQ{W`IW_YbVELq-?E1|LV{H*uLgVu}xq7Fs6b`7mDc!p~$(#Xm z#OC%dU6`K+FmS7$AnnH*njkJ?co`tB@)RJH(D9d_#H(EfDIeDK=6gF3cOXY^^r>;j z`az#DmtATepP;0GnYoeu%Va`H3-)sA2Y$t;>C>R?&dJ`L`XrEf-v#+OdEX_mHa6Bb z24Q#K+ySc)sw(07Wk+-UxGE@-2N=Hou&CjO;8WGD1OqWyI(x zc%=I^p@;KbU@{_v{E)f#L581P-tn5v<*z;4bD-C+T?g@%{Nw1FN8x6j%%(8WSP?Hl z%f_I6_C`ROMU0bW^eid3wSvqmPKK!(8Rd@KHIe?z0Ccf)-#So!S=S&&i7Fv8W2pkN zuyS9QBUauJVu0o3)Gt9zSZA@tOyKjy)C~^U*@vQ6_m{mrHPoSKiJ`OT$8IbV{l#9n zgdYP*rdSd7{!bn@aB;k8Z!go6%?kV9?FQ~NEC(<;wISt3+#&QT!c%&;v_eDQ@Z=5n z#|=!A`5B3Uy7lF0?88jx*I0tSrq(7WQe$YhtV-S;o1FI1Etq2!g7Lftf+ z4qB6i`Lz_da~^94TIe$rWuW`VMSrYXEESD0C6`F=)88IVQF4=Orx%;O=GY%Uj^BvL z>H$}R!Pw=g$mCn*`=BRv0m*{bDF{_H*dWC0R|*0hJB%&`3*2xgC$L)0SLj7T+d^OG z+ww>Ch@11F-fSg$I*1IBxY|+FCPeXlfoqPRVC?=>`{oyl$meF;*Wy$jifehIuKl`y zP`d)HiHly%B$6h&&@S?>=#Gq;rw}IB{{ZBcq%ZGQ2n-z_-$+zK&O)=v0u@1}H+iW= ztNviOvzWWlJ2A`3_p50Vi(iUR{B3(-hA%k*z6bXxHq~@1-{X5hEmTZVYtki0!qa%M zMN#~rdrcpFzjLNLoT?Mz#?@C!|7m{0n5w_dlX*axyz+p+{eih=4GE!po!1!_`v}Cf z3e&k3Ujpw%WT?J7#}Z@@sTcb)d3zJ!atTtzdPkra5|oIg=j^KG5#_Ap!xle@N4#7l zK79#1nMd%4uUFH+^Y2ASH~23`WTLD7whLA|###UvD^nN~Vya^Ao>z5!xXUY~imQ$r zY(8at8;U+Oob*|e^N_n#CWaiFLV%Ggib7YOJepj5kMo^e3a&GgJV6VY#nbH*=(+!0 z4468b)C-c}@7_xzfftMt87_AbT8cLG^k-DHdo{9@iaDGgCL5CZrzg*T!{9{edsHER zE}`LlCb0hXAD9czg?>Xn(6)(7`N}(SNYX!W_%0U7An4kL%A+)&3!_aQlMnpq*)(el zEUwWRO%8H}73}JhEbW0y@60sxYK77&EQ?5k)zX8)twYLkW%2S(p~CGW8BD_ssZX;S zezd@3lQ2wU(p4ksRS3XlTo!P`6B=L9P%@`Su#sGFA0_X(@<BI+E}OvqT$e_3s^2W z0*6ZcE7;(xnFr|}1VPZ>8r+g-jHB1%AEg)WqLhH2PS{sc8LXm+(vtx}-h1GX%nI>Q zFX=1gIYK7pCdj@y-sFCiMuc&UBWP2y-+D%=DTZ0jv5Gygi|d%7cSCJKj3 z9TlS1=cQ4zbsH+4qVNbjx|c4H^D#}jPb7*^H|IRs5Ar`K{<$E^$lN_z@!RCE;75?4 zVkTxH`7M-<@a9jylGqlfCtGhiFACQ^X`~Win7q61|Ltn)1rdN!w_+c7ztLqGW0520 zKTekqpK{r$u0@yDx2Z~l!irsQ+d2-n)Sb1QBHvr4&xV41k*Ld`<4^Q`E07F>Wi9=a zZ-F5o(awbCFCixQJDZ&o@~2%99OePG`%sj$nNqk4oTo&1;4_Tl<uowjC6H&<*k`%ka)k6Oz==S1s-DlT|pLPG8rSiYFz*3>qkw*Rfz3TS*KjKJ1%+r zZ8yI3n<8~>c-1a`t2d`nYhKvSBS2^*bm`Pjy@YrqFB|AD%TZge%+z`DR+o9cg}&#B z-MiKHpA7ck#^m!OT?sT#$;namK6Z+&*vBxwUcseK^f<}kOCf>D9noI6mW z-}?oT-qW1MIBeP@%pNwJCt`)K!pCqp3)7(&KaQGU(L%Yt(M9ON`iqT3u4! zaw&R-S{_IcQD#$ z>PxymWq4@nXq5x_e_ZvK#N$v3# zR@;j-SPnw^)J2{exMhIIpL3LYL{AjLx;xTJG$+0JECF*Z6wR##*NM%@O+|drLGBPc zF93aDl>%BdtR>lPK!N+T!QbZ(1l=?Z@tKsbNFq>FTPlX9kMu$@wi@kB`nRWFq)mCZkA<7J3I6v~(-b}iBppL+egWZZ4I z>}gU|QNB2Y%HE4uNT*OhWu4OMvlr8zShcgg&NNQI( zHjYqp5eZG3nL$|N?p--9I^fxBhJfHPZLJl>Z`t#Q(6x*3B;if#{vR4&sj%$0mAy~zCY}g;wC$t}L zerRu_CyoudzVq5m#QSM}sfTZKYuuyyZCUgY;#|l5Lwz2<56KnnP2lgu{B7o=eKR>x zgT5Tq`^@HZZ(#dlU$2Kyqj7YNFm@PwfcB;8)g79SimW-@cFy4E(%t3b1$+a$ zE55~ZMWZ*7$DCMws;U{smH?&0-qL(Wx{6tPK^h2Qf|?_Oc{D4k5;9`P^3iSzw!d}= zzh$UCGwjGMS>%HH$)j(fZ;m*7JaHYH7{<$--w+>E*v(Bd)IsGFqI8N(?y0%DDhg;& z7<|K%0rIYsED|Zn4$8`%G7-J)%Sgqtt4oB#6UU$xq=FILI#GqQ!vT`Pn3T4i6NxCx z&39w8l0A^ae|7J+*WZdHcltXj|DZ=j2l(Qa6pBssK$sWnMv5V$SJhY3%;W5<&^OF3 zY#SFxl@B#*S|cu;#x4D0wQJFKTcJ}_<%G~S2s-P!M$WgPG_;L(nrhTaJ|7+>9Z;}f zA@_D}bhZ``pUooni~(@;=ot>R!_i_4q!e7m69BbTp?R2-^$GTPF1&~=0X}~O#9%{W z{nQz>`Sk~G=X=%lUq?+iued~g`js#oVmQJt8|S3CE%1BlJkf)^TcFe;OSt*+n1&KR zu^N&Yp|Hi0G>fNWggopzHV=$IvPrds>R|uO63?TuG&Ma6`vbf9eQr_p4NC8GJl*~g zYF(1epw7)1ZW0|bv0dtvOU>RP6v~U3X%(NL1MT`<1Ntg?$KQ6s!l|*KHb3#J@H>Vb z?gr_W*3nj1nSaSS)|7YhOmZs3`8wG~N2fjGSbL{e%hmKKy}YpKv858#9W{GRBsPEL z+xdXu;{H6l5djh%m5S=@BVS7;GY6XR8-F!*x0xs?(E&MXBlst$+t2;C3Pej5zL z21mMYmX~>JGl-->T~*u8`4c1(?T_cJI}O!5i&Czw)(>5i>D{^PC#^vOjVOm6*ll3e znTS#}Ii_tMX(g#%>9ZbQmO&)$toZHvltgZywbsZZY8OaI4Cd^S@@sL5F@bP03V&Kb zs8*e>j{N=Q>QszkW^!uWD4vkuP@d&t9zeOEK65teJ#J;H#q_5U?1{7%JsT*ac(OdI zh!)}sK5U456E}Q5SCBqtW8vaGL!%-o~rqV<^Vg(HYsL8KBv=>EU#Fr5WfI0Nka5lbO zoQSck#hlK7BrZghK?|ur3UaCBqDy&s^5HLB(ek5(hrbF-n9jPGsnitcmJBZ~V?u?u zf3phYt*21WD%)cI!LLYg3+|-wB!Tvkm#wtbt@;sMl&AmWkzK8X`3e=WI2Xb8eq`37 zhpkxV5<{@azHhb37+b!+P(k#vPZ#iz$-RYIwy03y(*9J=`6GyEky@xa66Z|T5vqOY zqkJCJsUy8BXI!zH>D0p<3%Sy&wiw#C65X%e10~i1QLWo*)nxEw)_W zR=_2Ef(w4fvzP4C8_zm^lrQ4RXFuSgx>i&40Z&Jt4`QCw;` z4Lzq|44+WyPsziCV$?&&ySFZ&TFt$Tf3!ni7Wh^Rzs|Ns%xyx?1d}})*4;4g8@K$% z#4w0i&~7AgXa<@kBXWaPxBD2Pbi{dJx^fC0+zJuup@K2(cxFwKX36j^JxyH`c;`Bs zP9=V;^|~QGmUQe*bME>+-2eq}Khn@_ukNpA%w_`Ba1LubU)xxDQUve;@Oe zfx9~WDBQzbsv^O{UeTFAFYX5HZEjClxcZKbc@bWpa5gDT{S-32yr6|`J}>;8QM#A% zD?Xn? zW1LBEwgxwjdU7dHwUsG_D#up*%SI8`s|nWWvby#S2nRoCb^1)#0v>S#I2<{6f9&TO zExF=q!`K$LHG*4q3QNCM93Y)=izib=@V)W3)oTo1etOH&*2or>YY4z?e?7QC&s{3j zh14YDj%jG@;ZZ`W;i8r0GCSwqEcEy+Z{eK1Xm&dhNmhdZ`SL#KK~b6o_hOoUUd#Y~ zNM8x)aRO)*%LEoir@P0ro?|>?njrS0b;MB1?cq6?Gskr46p5lZzfZbbbLiUFsI4#$DEhkl1O1((&cf5(T6guT@nJCxxQ!-*QEJ z$`EuAJ(0aF(dd3h?mdMDj_8O1cZO&&^KQffubErB@7{Oy7BHRvAtsTT{>gX;y3l>v z{NiZrdKOloAMY;W)TC77ExZDab$9oEA(pTw`ed%BMj=P-w{g-$f39o#GJocd4z<-P zrV!YJ%RAq0PM$NCV<;7Ylnc|4u)c<@vOp7$jP1@F+uyoA0aMo@sG#pfn zbnBfciY{i_bxE|;f1TRL5l_8LVP?z# zPS*I&^=jkRT{J6i~OY4r$f7PCrM<45>s_kc30b_ez z3!}=fc}(7ez0+#>g7MOM5sq{BRCe=^Ji8^r#4w1{e)`N~FNaV(E^d#|tROseX^Xg6 zj}OX41*yk7xS9d*Dz@J!+CWHC&G#&m5_4TWuE3Y|swoih!LjMJx-y~V?j!)$N5~qEqR4qqG>h%_= zGlB~Y0f3ckKN-vFVN{ZN!Ua-=~nf>(pj0BXMX_pKc)!P}Y<6hifQH2pe_pPB`Mvti)8DYc8bjD_@Cns!_lA7P|X! z9(zd@$WW2yRvQ)U_VAGLAR`QoGO*{w#H&d$X1~wrV1aP4+9#?9St$PW-0X#L13TKX zWP%ZFe*~!qclZ@2Wg;HZkMA6;blMQBcNk2d)Z`Fm$rBurxYvv{go`_`HU|OwAbfYJ z_x3HT+vu*2p$@u)+s3Esz*VOg0@MAs>#*HQqf}f+PH8|X8FQJyjGgOtc(t+<$!AxP zbVXDf?(jDAk680dL97^*2sMJro`P|F=tAhtrqTkpVj(IXJS~NduwvA5 zJ+jX;<5~IlnKwjdDe;7`j2|f9b+NDXM1w6q&6i4p;+)uTVgaycYr9poF*WJjn^4`D zNn13?P;K(iYpC!Bp18|e%ZR?1CMN4w^LGtOAnZ$4JR?m<<+@co?goYHV6iyN5yWzY ze{!&KaRYz2`kinA^D)1z{eC|6#z-5J1vLkPO>=mn8>b>SXgzhI`hqi;ly@bo2Os<3 zhSPQPS7PGUM66|xJ7>*r3AGn^Ay|E+NosLwE zv2Czh{wZRrlacf`W@|l6kIE7ozEnpg&^*Z{y4fIf^O0rHeNcaE3?HaaROnlke^X?# zW6W@>Tb}L;o@!Ig%GY@4x{w&F(=dQv>=fmS+I35KT}tDMw)BUi?^&47b0D~~4m1-E z`ne9~{qsSWR-^|jD(BVAeQDGSra71=J!S*IVBk4MsI3z*#?M5%)@M^-Ub8QRm-waE zfKx+Tb{XO#wHe$(Vafo~A4|aIf04!#qEqiAyWVtP(K#g;%pcJl`C6Z*pKks$lzxXzKZ5DsnbV2uo{P9{8QcGv4tN>nx;pvvta$BVR zm3CrWp6)Ui?0T)->f5l0SnFFDEP1#7rv9Z1*Uqw}9~o3NBZ=ID#DN21e>^4LuYQy* zp;zcF@!Ehp0L!RkPfoW+WGsD#Z?oKQ6xrWC2xFdlMe=bGm2q2E;26V|#1`^FhfP+@ ze~eNK&UBkRlyB^4F0j5`XK%Nz$6Pw&b9NwXOjXr zRQlw=MGPnNi(H21t^z^a0D}1x;L>PW80-!n!G<;M4f3n){ct4S~cPcRE z<;1PW9DM0gLC9?5+ZMhuz_8VrrSkpkW8=b|0~__Rt>acRuW#72|9&Py=w3joe~gy2 z9X!FLjS%C~H2PP$idYug1Y2#64q^cJWV@{<0 zjJ3+aE-q}l>pg$%G>%dXy`6D`uuuy_%NAm``ZimrdN=;J9w5>Fqx9qzHVwhi4*YnS zmFa=XqCsP1rh$XfHC9W53j>Ts#8SGZGXH0wp{h$!YYSUHe}<7l-&1UT;WrwrQS~X) zt_jk`S3^7_(vsLZ{u=ox4YKMVZXnAl<@>)4-r4OnF_oAh*KbY5y{eDK~f&K&oO~N%$PZmPHJ0iORKO}7YfqPtkuGE3Cu^k9wJ$`u3=P-x( z`VnzyefH=xe`9MP*4cy*)4sV=nJ6n|gHC4D2||%OQV&_%UGX$4priV#{-Ki)KPQj2 zlSC?Ru=V=gp5eH`P9(>i(ojeiRIrZu*M8*l%@u@SXg)DknsD+)&Qv=JI)uBGquzFZ zJpUS*GI(@e%;(U&xFMI^w{SM-Big(6%epDuHTT<)e_PIMwV8+JHKS5gi}#erzA-R7 zRfl$I=D7n?vs#X`*G_;bsk{{7yHL_s(6D8ZK#g8gPMB~wJ+zX!NQHbps7yq1{}AFc z2rq7HN~c=&;NZnZl~yqkQpe=qS9>cT2qH)ti^h4Dv*?VTwB;f&ld-2HFj$L*UpM%Z zU|GK_f1CIDI^w!6i;gAC_ZKaw)4;%k@tmm>C+Wk8C$7wl7D>b68t^oDmNCIR_~mLl=0?-7qCe$8fT6wNfC3Hrf3JFnLADo(%Tf#2oC&NXzo_)(FT|kR z!{Kqbp!Vc4=b}&!9C7!@&c?FJz`l};(L67Y5q;|ff0$aBdu1d&bcPkFj~dta%`bub z9pbtRCAGO#E{>|po8gtMfV6;B>o(IOoqh_4eMMcm2FiiDtWvr`7w9`5YkJRqu=rPv ze>$3^zN@a*+&uoN)E8qb9$s1Iy|bU1R+OWLk*;V!!;w3(-7r|$--0<`=^h&?gw$c0 zWm%fCq!^!(#W4hL_%3vnc~#%{_sd9Y+ZegK9hR##;Pn-5?pfV<%bpr*ORQ6cs%KKo7AC66MvQ@**f8f&nv_5qS?z67R=tbo%puy>t~@Y2F8F-7bP#Ye_mui zLz%44e)>tmTetk%%MarM%d0zFZ@t;lJ2}q*mf;*M2J-T)K+P=+9G-X+;sH{Giu>g$ zi-SDwlF=rg64bh!?$vT#FOXP0+xP~V51(F3J!f0ipIbXo!c#I9-I`>=iIIx8ajBW& z9#MuhI3?8WCHpQ}Fssv0;8RYLe=c~m3d!VVx4f_)_%)P99no?uPPBVm)-(9gTn#Rz zPi?89veE+UlQjmu9+ONpK{lRh(1JIq1z|8u`MG?!M%ZU0sS4L#ZWD=%v>c5g`s&l< zjHcJj{b*o$><7ZI8XZ@Tm$p+4cj05*Tx%X&X5#v`*dx4ks|K?T^McCle~p|G6YZwP zX%yCC=A5OoqF9o(uTqV-`!8kJbb3K#-hx>eP7hvU#K;^2iGVq)_PlR_DyNszC z<26tREy%Qb!%y zCtAGbhK@}@V7$IHBHUY6=|C>o8;9Kn6d(irV4^1M%b@R`mH$M9TJ-ff`a-?#^7TWi z^-*^%xOY4@Xv-@fA^Exenz`&;RIQWJLs9h)_729`^daGOkfGG-Y@!4hEZ+}?{wUa2 zi7B@GknS2;r8spy)UT#VV`ho?%Ihd9vXf3thcA4X(x@~u&wJy%}B zn3!L1Q%Z*xdM&4U?7i}th3mvj02K|YH!2Rdw&nk0)}350q<(1Bx;Y7@TSGnOeil>^ zC3~WO<<^G(5-*Pcntb|DWdtL$~9V`;Ua2M4V+e<$?Y`IX->6@(OV=Yz!L z9a;WqrPJfie@qvX1mv(95CtpwdY*#409k|rMbJEB^O$$5vGqKYrn2 zu02Zz_A!qTifN&uIX?6SdXos~n?ge0t+qAE=x1T3}uhbVHt z^g=0Mu)-zv!PI@u^h}_W5CgJ%TH_ZEie{mruwmr6e}f~2fRf94^+aB1X@YcZqw=%h zvltJ&!TzHKxfXyE>JAZoJsQu@$fk*P>PW=CThDl5tL^=6BmX>C5;7AO9GdueQjb~G z7uhWa)T&c_K_#%-e7e(jdf#R^z+JIAijzP zfqGvoe~kHw-{_OCz3O`V5!9SKC8oi68M|#=I4CT6>Y^ZOhs>40DII>w+9l2h;8v!m zv1rWliXykf83JunPqRIlb=PIrCYuqz;xY=1qt%qio@BUM=PYm2mKFgfuOwl)$|PWY z+Mj|}9l7dzFK(eDu18JDSAJY5P;LCdx=k#{e_p7u=~Bl;g9zsc+8;N;cp!SlAk~|J zb|L%8TH@kjN}Fs?{HzqM&Q)g4!aEHxY0gv(^mHW8gwcFS-{y-pJ{q8*X5z1CmBPwD ziGOLF+2S7F4Tq_h&K_N4WfgBcc?y9W&aNEy64)=&K>-i|D4e#8-O3=h-eB3?X|%aa ze=10@xEX=LA-S55R-$B`{66>lKRs%);vKtl!e9!$K>#far*}0*!|nSm(AdKt#k&f4 zOwYo(YXyyE|KV9T~bjfL}*{PKH zUHDL0BioP1giL>GQ*Kt|8;7nRXJ=4{I}hre4j3OAV+uG@WmuGGAhvHDa8+RSe;^g3 zgLyBn{n~U-WA!K+zB*_|qp)9b)fq68Vqm$VZa;6~dzLK?Y}593%?K7MP7Oh4Y_Kg1 zGg8f>ny4=y*hU+ITP#U_6HKw2G7uQbT}%ZAFiXANsF_z$%j1xaALvg#`Dywoq}lBP zd$s(y9;On<J8EQk+VBzGqGZN^oEQh_yMm& zD{5wGnF=+V3!D)3%Eujkdth=sFuXWOX$F<=%X=x}y?~^Bd)EHMVwi^ae>O1h&7n(} z0@l-k)x3W4UNo?NMWp2Ml!nK(L0`z7Wk_Ov&JvCCa~W_RKM@)Ju=g~yUtjKRyYQjs zt7;FsUg#StB$#2s0>Ss@GJbim_J8E{yA&^{dsZTlEr2r+{53PUO}AMs6QaU?V4;X% z%XHF>yT(UBJ5t#z^9zb7f3G<)V(} z1~hOlMSxqloW|X?zq%pl^Ac6STU=6oD6Q*L4PNthXY8M98^6z8pJSi(_BzP3D@feT#7 z`+QBgGmKa&2S^33KgHNMdnTvay{S_N;KH-iLCB$h;ZAD|-%Y_5qy@3bKggV-p83=( z&?%XWZ;DlT?_CCMxgjFDTZPe+^}d>;4V1&4;Ov^~-mH zi$!{Omuro_*164!-i9RoER5V>y_H!YM7wdq*5my}c{lQvB5xsSx#hSYiLK%#$`ygD zxtRpWG(HkLotOSmKDSYr@629pyTAjM2!_hWdwHZC6$}7#gxaDCGAWovAhZwdX17$YPAZ&T-6SWt(az6kMnBmIQ&kzYp<75nAH>O% zO}iU;kUNg&se3j!BIW~oMQFJt)NU)z57|fG-`c>EvI3tU9S?EyV5R)(&m++x#Rh4S zkhWS^f8GAYwHVCAtoU;%wYWs{0-oSl9+2!IVbfro;&d9?Hj~H*&hTgQAg?VF3EH{m z*GjDWgnR||_pw;PKjU2`+`Ee%hdRPAD;lxpbWsCMgXn_}zoK-SvL3Wt9i9~H{ojwP zIizf{+z80usvp@IiliG7N`pf{6Ea1Sl7m^je-gV!!fmC;zX7Qh#U2mLu-s_Fi1;@P zaE9P-s*I2eSJTFq*nBLta9jZtbF*F}LdeM`;ONn+)Ce2Oo%+KfW72TOCIM=~O4>v- zOE{kc_N;s?Dh~e9NyX(~p!B^l3Jty3qj3`P*wTEVB&?7qYrTr7u}TH4W9eL=wZ(BI zf1Pjej(F~vY#y5zZc~(5Yp}okl5orjCw@@I_3{dnN)O#gU}+OQ?TSy;WID;e=@jIrG76W=nvq}nVmlHaUm#_-^X)j`;H|6 zUG}zI)i>d*P=!P)Utxl(tWUijsbtr^eDVs>pio(&U#y_6h#lnb+h)X1S=%wGnHy=u zS+{z;y3ZP9kc{N)(n_mSnkC*lLzFEAz&X8&G}C{^$;_wI&fjF=jOL%0_>IM3p>;dZ z)swOKnxg_Vg8oHCyQI`NjZOH=ewCkP_G=`M#K?x5O$Ga+IuxyU#3@txT%r}m&W#u6 zUS4TX=IWx(&vJfx61qUV&qDEse*=*RSSU1{Cbpi^jfW+7Oyhp!Ck8py1FX(QE6Ljn zI%Sn48QWKb{;5Z(sh>u8{$QkFZmFJmHR%0Z3S{mxZyi+c*x0a9f3xdtngsnTnN06Y zF*PK9c*<=_gL=;VzIH)~2VSEKHIt-i-(=8k&1%V^x$62rrRH%vL~=wkf7KrKH*1R~ zv^O80Uo$cr@D`k_zUr%Rp55@@(iPOoL@AHey|FQ4Yo9Ruo!DN%*nnz#2J=Y1qepa| zdSlF{NByh`lFGy9(d8ak6{_Bv2oU4D1V)2VHckpV7#$yL8E8$+DsC1gCp8vX7*)hf zHaG$#f3Kz-vKGNUyq0r?e^~1$^TA0m^U1F;vFmO^a>0RBqgDU9@k|CZ`IK?Ras1{@ zV=iO|;XIr$7hm;3I{lLfaMP5Ky}g3!g{ia1^%%pwh>uI{FIY$@uiDNw35ohSZ_;rT zpSFm^tKaPNueiNATqv)j_oNTR7g%u@cN6Pb1kw|i(v5{_1!{;Re{rNkQ3Um;u?9Bh z^d?u6Oj{M&N6z>xTq+- z8-I9{V>)jesC^tuheHckHUStq%4Crol4JEXc!=jDbOqKjW)M29mGI5R5wg@sqrsQ{5ro> z0`s+&5q6Eqs(e`m3y(=*#1DTHf|@X=TI$f3dk^sIvbYx~e@Vp1u%%BghKAl=vU*6? z3I^QLQ_v>9|KfGFrJZ>j_VjzkoqMtx;@6-9ZuvKa!#*w2!M;$cng_@T_0D}E&sSdR za>vj%9{F?UeV{7Yh&b`q1PQw1-tbclw68FhxK!MBm2rRh$eHS40y(ttVTM&W1W@R? zlogylBqi@Nf8(27qG8a|e+tW15%t_=hvXcNDb?t@9io7$h_n8z#BEhGJykflG|LS= zl&|de#6jh*)Vn{cWw}4c9taQllV)2{BJq|i>*mUHj7EP=6AOfqVK|v;z|m77vQ6jQ`PtXUf5M*Yw7JoGDp(xclH8_u7;>CK z1phVJOLoF#3d#Zh`sLL6Goya|QUJK{iHaPKN`_ls7%=P44tvWgSEUV!3e~G1eN#eJ zJaGq27Z_d&;!z<(60bT3rj<^1<&nG2m#Ja}L7;mwf&qLV#_znf;qh}H)g^`yw9s*V`{5!Bmy=#+DmC+km3uAD zoQ<)4ZB}1GpCCW?4w^X0b-f`8r$FJ4Tn3B#Wz*T^S1dW^6tYKAFeH3=<}k4TBO;P| zgTRG%^)XCV%eG*}1?8Nt5Pn=ypn8aLgI-&TfB*ZRlgnM_Qzdgl$VE4{GIrpTJ&LB| z0J_f>hdeG6K}_>Jx~FVIw}0xox}0qntke|i8tZpQaIJ5rZ#qhsD8I1^ke6z^9Lyh` z=brmTH=+8SdIk6c-mjYn3(-ukF&!`B9tWRXVRTVQS%&@bHsQHjMrw10uVmyx_X^g+ ze_Kf42`1eWaLQC`8xk&);FMUNt`4!@(_XH#1r`oyR*-3ekmhowXh{Xo0@Oagl$J!U z<^ebGRj`o3YCT2uP16g?c=ffYj-Xn~G{4w>nGVvBVgwvrTLv*?hvs9ad*(0zz{dTJ z`7we^c=-u|qrOO@NmeSJ%SVNL(IZ#ie+}@g9f36x;ZF*_S3Jhjb28OpqY5@+Nf-Eb z8MNzsv_nAE>E(-W6UuCsBh4xDKMq{n@B*nR4-u@abFY=mhxHFqK+MP*^|3aa1>(0j zMtXj;5o98zS+OQQ6zbWKxp?hxBk_jETuuJ=^RYc;%YR-Y5a#>pAY|Y{GFjL#e@%11 z#46C`;sZ`0al~TiQqq++(~QH80bFEXDmemZ@}MQ}4^i;H6-w1Wc(h-@GE|wKZ*tqb zPO#Rd_A*Zr>x!$8j8k;R*yT=}h@nq3tO>y>=A=0PvdGp)_6KEiR$Sn@Tu)QwU!hy> zz0GA)TEJ>*$Q@!CBXFZRvzB1ye_wVwEh2*78akZE{;xtHSdOo$?} z$Bk%Fv;+xIARE6359NypB#P7&@9bZKk>aqghTIyR+# z06n%}>1ckL%S#4Ttyzs(FyHYDf0Qh8eP<|B&Evi!b1fYRWGb>@RqP1F?Heg<*4R zM+}yc8AL;4>Wqb5(lmz;G2LV3Z1BUTl-Cn!9)yEoUzINYjGisq zbUK*QXN7$t7wsZyuD1d?t9r-Qh^B0L7-h*1kpvmUKPih5HiW&4rM~RAI%_q$Od6th zgy4J+2@U7+Zyy8x{%MbMxwG3<#%vvJ)xG^3Gc~{pc8FzU1UiLoXimkhxXz8yKV01 z(I1x3sA(~ime9DX8HpYSjOc-tnM{vkff%9t& z@JWX!k7|F#AdqXkgu}7eQDOc!0q(HW@~8Nb$ct#M&p0JTo5j(GN8Sxl{nN}+@d(Fe z(DqOPF|rh}WtYLfWH))PZK7D$jibd(DjB`M7u7cqFi=GVGY(9$- ze`o+=_0KkWv+GI2Hi2Dm{bC`Pji1%6&dK#(0c_fn@YTy{A>jpI!>;^Nck&s}%@-(J zP8~@-SE61eU)e)AoRmq(;%XgXT@W<{2zrr4LMrdSGs%shw$Z;m)xm4LmZ)aJ9XU$> zIMrO;aa2b0C>jtGz7zg~%4O4O3F7`>e|;!yvj z!Czho!fW#r523REao4F+KwqyU(IJ}pM9d59l`TJ<^z?hf7p2Zn&;6d-l%W5_P9$o;A>!F zYmCrm-xc)8Ve{A%uQe&VJks2tE7pgdxt?WY&!_iu)r#HFSSVnoGo-0Wcn-cb&g|Fu zA$lv>Ae2J>C+?{=LP9jlo<$zGK5ZmNrCLIdz($V-Y9404e}~ZCsdtiHyw4|`Q%k&kJAxd?ml^$J`O=~>7SQf7sLKPb%5Hx zhk_nk%w>0yLce+uU9=OITucVG_HheZuCI$y$VYmFKsgyMI2HI4;CHL%->D&I$v9WnVs#o=Sf1DIt(``xF)$Z5w z3Q1@f86(SnOsm(b1t(bIkf(g_rK%N6iwO}Es`D0SB|?}dtiLLJAVZzf(%(iz!}Nx# zxA2LuvNM28AbNV8E>D*s>y^r{H$u-NN8odtpdb9OXOpacW*1~ZzJwR7v4_;s>sDhcSf2oJKYT0%40=X8Vr=pduH$>CUNMO%k#?Ue;jurL zb-_lIBM4$`_gFp?riN0ReYdGgI}fU-ZIY6Y!1V`xmY|!Xf9e8+^gb|>W?XqMW+W;oM)t z3$ej?+6r6)f3kvy&;myJ!+oFo2_DMK^#B>u>s4oEAxL_9kCU)BzSOToYq`+N@nbD48N}R*GQ$b2`wMh; z3Pk*CHo7&}sc+|?8^1q=6HJ}vP_v~jt9W#l9`(ISe@7U(r&(|V>6q-?4U)iupy&tf zq-VpxT|h^i{}{dy3U*-2X|?&6MKU01(tyNi#M+D$6G_BlK%;W$UkWPhy4q@^#I6Nt=3GSn&Dh*$LOhi>v6049%CG` zeu>`wf5UHFnQD;05cdyUmHQIO!k+1A@=a$4G^cQHpAv|#`0*5}7)ZB)BMgRW;BQR& z^#mqaZoXQ`O}7!cfkCvp2=*>$6)AW+3Gqtw)i)|#5O=uh5;=+~OKQ3o*S=7454MR` zoy0nxj)Y%v3Xo*MorRp)h(9FBBK`Gt-3kWrf7pR%+%o0bT-xwy)OD~r;>JRx)@mMB z-*Ie{zz!pM3Z_d>j zSZ-4o6tw9@h-Xt$Jd;Dxog)d>SPZfNpSw&{Mgt#U6hn~-rNz`F&HopG0Du3diC6fH ze+|L}`obw^ykzdup_hgFy{y}K$_RnwOAnNqf$8ZDA=}N0i5_YIclQ?@`YY~M?$h0u zTKK|z1h7(3)Z3iiSlVo?l4b1xUtnK{ncU2svb{|%O9PtSlwj2vO3@)NGt7xjN|~s` z!pZsRumpyo+$_3G_4Pm^aBH8jrf5X`mx1&F6ahJxpMU`tmq5S)4FoebGB}q}zyTEm zG&D9flYvAhf33G=RGi(`C5k%)f_vfa7ThhkLvShFLKW`r?(XjH?k>Rt!QFyGu$%Xs z?*4k5+xJi3??;XC>?L!}wdUG;jG`h_R$~%1b1(r)IoN}l*qB-Q0E$+2Ce9!Q2YY!Y zRiK44;IEMjiHb_x31|$qa$1_Sv3T0k>^1ke<~f6fkIK{fbPNoP|7H0n1YqL+KRtglK~@&_0P4RVEC`90rFO+Kzk674q)!!1hD=00buH2Z)WvR zYar&oe^{a*fH45%2sE|&n+9|<1v>uYVgxt>o$RbYpugV$D-giK$=DwJcLrbwfR(+e zt+Uxb1peC19sWhg(aGU&gxz1?Uod3{5Ex|YWaS73{H>}iA@y&bU`u20Kea(tf878F z^S_a14yMlkwDd3EUzopMu(6dr2ml7Uf&Zyxe*y%US%DmFjots&{tM>lWc4o^&LAs$ zi~nN42yg;g7(1ES0zsg^Fn_WCna+Rp3HaZ-H+FQib^lkk!@r{b7Y8da2xx20jKs$N zx27rhZ*2=JdnA^B7Dd+H+yTJG`ft0Lv*Z8txd5I1H6Yr5c82aR31c${ds}ya8PFVw ze?`#&{I?{4_Ww?0=KnsC{~IL!ZxQ&vMc)5^;{K;b|Jx=0|9hYR6I#mI)>hHj?(YKp z`+))cePJ8`@_>Kd7+Yhf|5v!Not3To{~_T&1GRwvCi(w?BMUbEI}A~Ki@$=fGPC~M zXa$n8as!$vTY*h20p`ZGe<$@XyN10Pf6&R+${zSv(SHpSz{JMN`X4@ZODj_w`+r8y z^=}u@-t0fg{}t(9)L9giv=!8382$i&XU1K|E!@CzH8_y3{VzhKz@>#Sf5cCvB<=>Bb)mF-`R|Bv5)o%H_$e@4>Y z)WPhZT~PxY+nfDeum5HE$8GBDrHhaQ|e~yF&@D#LI z<58v0tN7*&fy>o$aoER;^ZiJdrJCtx2AWu}rvZjn_lQl1R9tl1t&L7t`dcQjj9Cb+ z7J}Rx2Qfl!W&3WCoO|}o;(f~z+`EA!6hk6|2iG0sGNydz&K=RVIlg`CkhKV|CQ=!G zh()*M?4mcf@=iZFjE^Aue}G>~*dEHJr0bivyn1uu=oVS3<>H=*HW=jZ84*L2fL>l) z-~D*>kj(%>#befJPJUMQ=0Jd9}32V@B=yx8U(Pdyvvr-fA7%-->&?m5oL>H zn7-Fq6f=ROZ&aoi($m3TE*3?5FB3OJjl_u7t_~;JR|#T>cZQ_S3?3nR7CY1 z4}9uY<&AAS*IO;eY9JCrJW=zd$(rDZEm0o6ZksgKYTLAE)HTUpnMHV*q+~ zo3l$2#Kj#Ve^CM@7;2vnXtcZ72&W;2Vty>S2#o`q4iqKmBE_r%#|=J~DF13}rUpkZ+Pd#sJ#M zZh_4!avx$>67h!Xf&s6bzNnOJ3NJj7z7Tlg3nvv-e@Kl^K04QCG~xL!hEPdzF_vkz z+fBVaUq;i+yXNH?6C{$UxEMM zFFV_rf46xB1}D@pP%eZBrF>!QlIvipuRb#)!BH3GcfDXjMSy)z1`4A@z1Izol+&2? z5T1`qAPn5|8m<$$^oQ#cH*Z%IYe-X^h6h9Y1=CUO<<)ahy2VDZM^fa{~ zQhM`0SLzZK=$xf`Q!YA!R+MiGPW86gQ#VC7tIu#ASQGxe)l(tmg zf13E-Z+^P|b3R6+oV`RoLZ}9C?VFcCdcE_nR6c(U65|bR!p88TwyPW!6&QY8p|ay5 zd}kd`8&;bS3Ta1q2VwR}tBliheu6LqwYt?}p}b;WfgGA_snWWON>K}{mZE?Vs8?EY z1DGf4C#Y&XtCH#FzD9kjr?ntS$feF3e@aDkJVU$ZoR?&6rsbhGU{k{|b50c!CT~H* zXgU+`Q%vZh#@C2Q$Lgs|S}NE}96bw(?}_d0O9D9naU^x4S9=eb2OH{;Op+Za;JW-` z*>N_la~y*m1Ah+N9fZ^FJ8a=T{G`+L1XuGugoWm}39$tbxhighA33;k*!cFvf6Jw^ z8eMzQEp0xOgO_Ht)@j`F)n4^0#})PCi0!N(;Q*TDZ=<5Z*9Z8-yz_$xcO0{G4dZlM zckt)qGv7Uv8bcHWph;n9LSZHjfC}GuY?bGiz)#dAsR0Tmy<|5;Qnlky<)p9q=sGI% zu*+(HI9y}>`135OZ&u`K?KvMge->&h{STCb{F|9%hm~WI);~(AX!125hg?|Av8u0` z`D}`JE}OcK`H#n7C^7;0jzC(~uepU+qKz?3L)WV{?De%lccO>O^Osq>1P^tl9u0yk z;uE+cu39oeB`YQXJSMFdJcA#bErRq6Kbc)j%v1nCV&^DH?0DM-#n)u7f5q%{M1Fq> zxk&F5zLud-g{lA>={BO-Z(1`OAWI?$961ba{-q5d2}W|ClKVp<1N}B1X!e{d^Ll*E zJMlsQf6Qt}ue42)VE^{=8KTz=d8g!o;OTN?(~$#;qjEKMC9o}q9RBOAFp_BHu{6Tj z$I#cgk*$iX;tgXOY|8}uM?b4kvRA0SHkI_Kk8(4hYj4+<5$ix3zkJ|-4Te{@?3Ey)qfo}yeo zLL2XS8q!375Z{NJ2?MBapW#BDBqP$c>FFk&mYC*QrMb)asbufj_@-5A0Zpeq{Mao) zXSeVUh-~Lncr}f8K%d67(kW4ccXv;rcC1MEnMQPWXe;Ng^vV85p;xHrHc=Rx9zfnS*ynze;FN?^V;o!JwY5XfzQQvUpPMJb8OTFxniVG;_w7Y%R+~kz9$X4 z!Nj03zKg49!@0FA-V zvU-L|?q70+9{Da(*pUQQig)_4LHricvu~LG#8LZagPx&9f1BPj+xSwE9*soSF>HRV zy4ZD3?VC$!%cSLY6|;qIo@Ci-#&G0gx-;x_Dax%!_)@&8qHK{Fb3GKF0ifLzP~k1{ z=yJ_VU@*CSe7jBp&q4e^$zx;mG|&ALJ*ptw@3x8Hqs6X1&}gsTfWCns73t|FEL2FN zUbD+7r*f(_e=?AksboTZ)T^Ug3QN-;c?)y}Zve}CInr+g#%aIRL45!Lp)r+{2~zcTp1d%&@w zu@hd=So%1o|Df3k6;adUJVu*>{FK%LOwI5ZYlfdge+|EkO8R?fTPorDd^BVD+L1KA zeKTj0ts^DMdh@nGBz9-|h6cf+pfLN=FR~ts&R=S5A93<3k&^(AEsIVN4)1*Zz6t;q z+0Uy|i1&<+qD7&^dH6LQ}_qu^gq2Wowa=Rx0`ltYV~aRi2O#iu7V!G;%`;>Ddcdgzks%0MMv!j+8s^!r;f z9Q&uiY~CYrm#u52BW9a)!}~i8ixaztIC82-f1E;<_2_dtHKGD%&c^!(zS>IaubZ^X zSh!f;;wTWPkg$>!CQ>AKQI-zmwrt{_iMN$pi^?#>dOvbmYBN6?QAJ70}e ze^v>1socB!@x#9S8H@z!N(Pld-KV*brE~?cKQ-A*uMDc*&Z!uuZF$M+CKqcz+C5s6 ztBkt;{B4$tz2GosP;c!D9TqePB$bkwRaq}HiX3c7D`2RhE9csE9nE~`>addeI21)5 zJyH_h=NZ|6TjL&f2MIbkQVMW;ytEoYf9|o3^&?}`c1tMC*IlhYSd`=8Vpy%3XI6Q& zq>v6}cbJ1l;fJn;0);}=^d>zq&McY|WCTXCE?%=j58uBRhiQc<*dEj|t@ZL(e`!Ek zZv&G}zkX{-C=OL?tH#4F!rd1CE}j%6kS^--EEYh_AbQ@Zcc17aP;0TTuKBzU7P4)0 zlGyLkz-m5lc9+lo0!)#<`o>InBJM}YNw`p~!oSz(%VQm4cSOa3cY79R2Y%Cb1Ay!0 zk3{x+e?xQ2QYls-kc+zr+c)sQfBhKK%GK)_{E>IJuuR1V>Y#%bZ8;`DWykpeLSK)e zql=|}S}MI0knS^TSSVtt04%3dB8p|=IseJiti8#K+90``A5C#4_D;1+`np8WQH1QT z?}}^6lWQtJq|g~#_6#Bc8#0t#L_*B2mh&^z>G#vdo35l(124DF$Imy6e_!C^L^?5e ztUA(W<6@`PSW;&eeHLyMq)=P-1+8m;`9J7oHujUoV8PARle$VyiU^~Ob^qKP>zHfv zi;A;5oC0);jyR zE{4qOAh0sPP^H>_9z#>e2s6pv_fg$5&uF1{KEvr+uvt<4rQ1L}e?I!!>#r}IF85rC z+$SDom{DivP!cv2>}xboKr0BTYhw=go?aq%1m-#;D`kPex(REVmBZ5F$v*yMIKXP}QZQr$MLN zqg5?N|Li#btwaa4=;Y&Vmp|iWBVe%4D8%QJa(2N10{M6}P@!;nUoM@_)7xj`OA0N`1Iht2fVW z4{)mG6x8}7r_?dvEjMyqa1=&Epe&WAV&C!?!e9+z#o5wYUCW}96zTSNQ%}-Ckcu3B z`LMzC!?*} zD;#ihl;xO54}%E{h7S@x6ce~`?O;|sQNyhK<@>S=Cn~r5d%uDwtn{!nzr-!5$1Ml(&vII9J}2eMO=`f@reF`@%wCu4at|t{C_J@tRUfcWc9HmK4HYjSd+H zJBT8M#ur#&h7A?2h_wvqsL*9%XHcDifpDZ;`5634kv8TtvZx+4Msn(K%I^e(PN#!Y zY2_gNa(~?{Ry|_(#dM*xceag0+c+fas!`1+&Me9#vmZ3zLe_U7ewIIVKgh@Z_Zqg1 z=#D;^Z!niX4nyi^=Nu#KsF3V|u9;yglpANe?!M<)5lUzm=Os48(GbBbSrB6Q+DzzH zr#P?toawkE`(HQFaM2HfO-|%^k&JsOxxD9>Q-5^g_uzW#5hZw>jF25q#`9(I{0+Xn zu8-u|ny64u{XRK#)H@3{H-W=xJ5fNbbn{rX3ndv6$cPmp63J2|E~>H2yrJ4CuWP64 zg)C_7+p?^6VKf|(a~dM93$kt>q>#j?xuuXVidT%3lh#jsTo*ek+dC(D&Wv7|z7+FV zynk^h_S5-eEYULxjDp=^DC`L8c}Y-n?o0{Y@d9Mbi?=^KvLv(+#2YG%$N2W9EyUBY zG7UY5 zL!G#Cvo(@fbfn2%BK}w)g&)%_K~`(i+J82pEC3gBn^(W#!Qx8ne`=ptgAFN>;>VF? z9-;kts3sAaAn|+-egVWxyGGHPf?b3@0}8H4zb?&5I7-$gHUm*C{&aiuJSAM_a*FTI zp#SnIt>^RuS&yLwis-5itVqhl#tq`CH0s9L z@t!|29IKII;cdtEPh&PqH;fA+hKsD&&NYSfiaWo@~#;+}pD@}?^nZ}D9E-)P% z;nw*+f~xuLHy2e+O7wYad)AcG-hYLu8nC-Rs9B#JJ?MMhk7FUB=wa#Agt`;f1@F;Y z!^DKd`*NtD&>syFHL*Fp4%C!KG>`@0rQ3jq!6=kaMl~bW+lUq^uMZo4%4PG$&R6wL z=fJIYlsgkIm`~P+c`(-rdi*;hUYq2W3+1=lQ1>p{{7)ZOVDoXz9*8x(@qfl!Y_iXF zEt|lml!BM+0X^w%NCRTqdx;jNmQB4(gzuhE1==pd>Wd3J_bERcA0#j)&=(NM{l4n5 z)pO!uB9|E7(7$|tg0h?5*CzfwN#>Iv0+IJb`iB1^R_cS+LvNP0&ivW14|=7yHpXie zhAvIHe)~HQgN*>~FLZHB=YLFQ$8p~*5tP!yD+>fC?|Km7c3Xe~V|FDq*#bKxQsu2< zR_$t!swYwRMuUvDwCFTfgT!dLw0QeN+j>TF({DOx9*A763J z18I?x!Jz3kzHkFdqnO?bfrg({nP@btwUE<~*!pzbMi)NuaCOjQfeS^1e+GC<3ycm? zMx4)u$V`ODR$V%1>3@or^rZ&9D^#^%yo1+4G$3>uW2bFt^?IanjoqS&eONF)IszY@ zs<>Gnbd+Tem|Swj4~pTI>ds7@6BpmS6$42pFf{l=ssW&%$*U3)8ACX4*Qx{4`b1dL zK=!BU!|rjxKH-|tWfY{c)ksysCx6_VXAWZPPx!wm-rU_DTcE=`SFU;XT!+JWlhkgxgG>E6@bQOhh{A&ubH~TwfQ`8xBrAcGBH$6`7M$`6l2C zqoRtQ(OW3hE(;s$Q z{6?oSzNwm%w@{DYe0SX2c^NWTei0g+St*~NliT-APo!Ej1Vdu!u6`O9;E-JFQ zUJTjSu78F)g_#ab2|Z{^fwIJu9crGJnC~~7d*z5nS1)KX8RD16D>hb|w`uf6vlA2B z`9Qm1gkWsILwd#4x6~>dLN2yR=5>r6P-Grd$&Lk5XJZsr6=J9QHFcnrdNlynwiMBp z@`_8>>11Nz#}8&)S+B3F2l~~>oK#RHDD!wlJb$}7TIZ>e9)tK#y5VrJrUf+CPRRPd zQJW1WC6Xszwv1$|)0+UObA@K4G-*yoyLF~pC9^bHy_ET%Cl(J1%H^x-rXa~4=$^N; zt_DB&uXI5Q8WxC8y;kcE^F*J#i5m6!SzBrP0Mraso#>OzJ*{X|4Y= z6<$jR=LG^vnL@*Ob|?U3s=Sd!9`aloP*?VALCNHObeIn5MFgzxQL1%rxTVpX@#s;-;*g#fx?AN^^IJQr1td${1$C6#nN9V4_ivP1$$v?Sr834U zv3xn)R{HCb)WX9lWrRkIWQ3E!W*?5&x?e?v310lW zzSx^NwiPewH2Sa8zY&b;gA*U@{VA8o*6f_tBvVYJUu`Iyw!n{3JBm3OV@vn;NBT5M zWMEUYsO5tFc|NgX&U2p;r+*bqq@@8^1L}R7=GL(9!fg;)vxkhh+mPet+?BSgi@RH+ zdY`Zidpc#LtbckPb8-tb|KLSAxVAfT@Se1)uPUxcH`pkc{gkqysDQU(F-SP7?J zy#?XJ6xBr9o~sYP`B&|78O}AOA)znaHq`gj^eVQpPDL%J2rF4KRxKwTt5t*szaILO zY;ySSjf$2UiK}psMt|?aF6MFTOa8-b+UyA0Fvq~|!sCN+6pud1U^a4yng0rfYbH-H zyq6ap<-C}@gj}}6#vHyTb^C{E-H>k!>Qx`HwUi~3A3=>v=Fwf|vZ_r^ZI)JAtO-dq zFWm%(PDB3-Cnj25$%;0UbiSX*&yP>(7Got!=~&JDOIHga z^x?11m^c-QIEu{>k8PIn-E)CDm3>qS6rlmuSo8iJ)+u{vmTzb z`M&1bf6v7a$$zgy52Myai2&)};*|Kqn-5oE7m1tXe}BSF-hMhlkb7=J@wC`UF;TRV zG+hWHkV`lQq;7B*B6Z+p-Uchz+HXkwFp&sI$h1_&VMzXMNgw+O*Hs{T@_ENwXiYs; zD3`)_@je{7&syvX^x1TdtasQ~LdLVVun62B&;~>SNfl1FZbg`htMK12AJc^w*EKu^ z);w~IUw>kDnxy9LG8S@t4$^#%^atcWf4VLU6GbViXl?uL6V&Z=e3(D*n`Tr@KFmlWJqm3&pk{{^q**l+zJDHI zf?N9-FiEvdKWNzcKI|=WgdXP-3#6+vGE|u}r-hIiA%nIqft76Ta%*G zgderOrqR2vsGs@xKdIQmWd-Y}z}6@Q4g1=`1c1MjH;K5RV6did0Rm$oRex=s!LFn& zCqjWgzPEW^@oCC7`DcExUPouK1wB`r6@|I>km&`G-^dMxyntTIq3ZFBO2vHBJr`WF zx`Ka=s}AYRdzr5mTAdLT^<8d^inpJgo?53TE@o2VmCZ0%fsR$1n?A+`0t?l^o{v7% zliXq2#CI6cRjNkeoQNo>{(mThA2)@|qgNiD8=JfuKr|Ub$Zdq*vpAh6)p6{GU#lPH zHO%YO%jsGDf3h zX?lHohYA4h8FeK~BZ?qexl3SPzPoV{Hw>KyA@{vZmO#wD`f~Tzm=(DX3P;h; zr`ns@=DeyUTdh%MRPBx>ij8a{N4|rq2C>xoVfhOB{|wL0GMLSVe^Y?XR$u!2@-SOUy+ItMh&pWDjaFnlC%w3(`tR!{Oh?eCx7QTxb0S8g7yK-N zOva!Y7!&HGJdDR(Dkr$T;R`Xvcqr$A;nVCPs0vl1 z(SKc2x{B5k(g|wr^)j#`YTtY34*~gJuN29m@SYku->}_BV?oWlh%y!uHbyuI{nohy z6=Z5kfsQrv#<{+UyuzCy({4tP^~o+yE73B0EajM-PpwxOLG@Kg28c2EuZ|>~1h0OD zkFR({KIH*Ph)CAljP}8>1$_mI!(>yo1%Jhzv}gj04Fm93AzoIxl|O7@H&wCDtc3_4 z9pXlWyfSpJXe6oT3-h<0NOOsxs9@Fh%Zb+E9B{OS*e)b*)%U#Wxikm%GjeTLK3l2Q zXlLHNc~U9FtB|RF`yE%-lJKkJXRju-S=sM*T#u~ij7|cqIiLh6#ere>+ifBy+JC~M z{>9R_=jcXxm>8bMs-@Z2E?EqJ9=5|)7Kzdt2AS!wDz87LtH)eZQbAPJYH!QBM_JR)wVajtg$l^c=@sal>){_yV#{2QZ zrS6}!UEBTG7LGjLBl6*F1R~x{87EwVq-pa;>C_H9|2oxcms)@Z`r~Q3Y$-Fs;o!&tl?X6yl zGy2oI;FjR@`^%dCYh_6z-K>LN8AxdR(OALJzQU;xC9rd?b}@U65q>dtDJ9|i(3AHmw$ox4&G{!?}f{1rhwq% zTi_OA0nReU&h2Klt(U6E`Uj4>{;hRXqXK@z5{kf2#Z0$c4LI=rl++wPuKgb0n+Pe9 zSeAY79_rhbTeq&?^9ncN$S-#JN%21V&+{@`FyM;aH4K6}W2dwdjneWy{ry@!R$j-F z`Q9K@+uC;`M}O!f33{?;YP*UqTrLtl?($&j>85j$Q7eIw9IFUxNU!uy<577IlWFvD zxtD`OyO#33$L*qKtnL|;t|T$doSBJ>m0}qdiSDYW1lbUxpLV1ZoOU;zpv~r+YK5L1@4)&5FCDiKx^$wKknhX5e?IGyR zRzF4T+kHL00F@ejY4pqE0^ulr3RgzTa^Q}C-u_506fKEyA<^Sn=Wx@sp$WelRZ7c-M- z0*wS8+>BeEBYL_x5n87Bv5mb}!kyxX`ZAE@-bkpQyH=b~&x#(ck(Rc8mgsN*OBR*Y ze}CFxmgy$hn!Z|+V^Cm;kmfmtZipJOeuB%)FNUo)Tn_oNAc4UvaE_5Zfujh4`xXxU zpfY1{Z)KG$chlP^QlnQ`DDin3-xN3;Gz1`Gh_u@6DRua1dE!+nK6E>2RGHkeemXqJ znq~B*rlUf=T^pfuESj2{N~NPTZ}56&9Di!)qbF*d!c+1MHi3raho$5>yLl-qaxl<> z$+5&n1{n!*+{X*@0DTGm++B?xu2!a{d5%Idh3M>q{B2i_?|yNOzYRg6br^^9Wd!FMeK?vZ$_Ycj)N4!|A}xgoYI?ZxML|%- zW3B4z0B%zT%=~u2#ur}^eL={!M4g0^1I$emu4V$&G6Bt}qw!Tso>J)$T@(PJ7S1f$ zC=}W!x@P<79~BgW9R(u41Iklfr++PQc2M!0lzAQ&Wud#NZcz7`tMlaQ z%}%W!g2j@8l)4;h1i#QRRvRG|-o6LbOfsL8*+3h`j5qI6@Q*?|tk~6ZPi`J@7}2n~ zv>=loXHTVOOGT9T#-J$a+<%vM$*dkf4X&iV-Z3F$g2Zp{FoNsvS1zN@3x8^;Wg+eO zBy^lz@t}jEclt_#kC9Evi<84XEo2m=L92KjSxtx`LyhD=A+gsJuxh>evw_og>^=D) z4W+nPj<8i+)u^XSiN8jz4vZlgIj6ESNh*UaqThN}E*L9w?{dmrD1UNd3)*C}f){6s zv+NqZ4?h_IU6fBp&h*S}IfA}JBO!kf8AX8H8 zPS1VBQ+hXv;)w3!c z0@(z~g~U)j1~Kv_X;K|4Ns5ikW@O{vL5Cu-a$77>tM(?tX%`K1GRP>K*`_PFCw)mV%?i)c7$;Mz=5_`3Glj&0~Y&*nQ#D^Uf=AAXQV zPCxXJ#%Wtryb2Y&yAv1h(&T8Zcxpgwf%@af6O6B{+)Dd^o0wB|IHcFk9qm}zYy(}4 zmse;DJAbcN@;UK+8tOiIA?ixgM9j8$5MZ)}%HEuG&5U>YOuC>S!FC$WO;fO4>%*I2 z?(@0MD?D-%(Z+eR5e$_t(e$U|QTc@uCnVjYw0R5$sc%%l$OjF>YtJxOr)M)w_?!1q z+oTopYYdZ!;kvY4h0j>$FGYJN(y2 z+SNtHq))JucW`zwuz1&xHQ%PdI%y78ddO^{7=o}P{Y0-~i)g#)WwWZ!b(Oad`)sFZ zAb)a#XYGW!I^r*K02(?KyPCO~_yBf8ag}SXW23q{$L^!;5S{Ovz@F z^2|+R$*(-dWYH$`ITPH zl6+KjDnE}!w62jpR*x8$#jZ}jycJCp4u5P&R~_Dxlg?8J7l?REOT8(af@0rOL@cBa zv_e(fKL}n-(yrdV8Reu51sTwu;X~^0d(2G4&y2rq7#q5me?UZ}$^RjAKtRBWO)o;2wAo^wPhB^F!KmJZ~|a zBMhUJLRW&fh+^K_K}w6y1!j%8IdMfLY@zhRm4(t8S&mBz&ehNagapqo*>ur8gWSIp z76XZ^W zVwBysYBAJGva$({0k$knGQufQ0`k}Qtbt4F5fqyhJP$4dC&Ve^ELy@FHG6KWSw5Kt z?6-NW<)$bG8$H3a>V}y2^0SpB(Fflkcmr=k06$CLbFgBBcL??f(c4b&xU6wT@1oz-txVsci@C0|4 zf}(&z3U>%DA-KB*2=2ihf?I%)5ZpDm>qp*qdU~Gz`qxbVsCw?%>+H2qf*si zlQ6e8gUH&$T-dnSIfVeqP&+eMXC-@>BAYtI(pAOG77BO<_)zKSq?{n8E>L@zw5bb3 z2%vuhF$YLPzyNM;0GFVkASxX|%HF}#32JHO0$|iq*I{B|Vg0A&&lZ50=Rc5VPiLql z3_$<<;0Cd^cd&!NT%IZZ*Nz$x2*AY(0~YwGzN`UA+{Fms9fC7F~Kg+u`Qu6RE|Hx@(yNU58&eb+ivda@DI!l z;`CR882`)+({mE0=JqgKPk=eZ0+oM5+1}+jB!KaMr!xD0PUQc9#Qzb2|0DAL-^Be_ zjsC|W{=c5*f2EdnwY60?wR;|bzb_fU^DSc!Pz3zBXKYQK0DtZpM_0)I=VodLwe|cr zj{mw*2l98a|Hb#O@H-dN=cY)&ET4s8-A z{-2Bf$NI0ahd?|aVAQ!;d$4e@b!tYMOEqCm|ERP@NW*~?0XNpIYMDp=g9w+3ZD<*#$w|sv*+Diw__u!P;82mQudN|zb zPka0H2|HJp41Gfb{a-szUUhGfvSi1g&#6(C8Ra>vchz`T% zT6rAtqdh6IiEwDs$^xRE83PKm;0rq*`iI@`>S@<7D2$=Mid3Hs0Xroj9LgGZ1T`sVx%w*WrFU zQ5?#8*#}ZY<6V|lHW#TwBPF{6#po+Bav~zSZ{exXD7b|K4f=1}W_)dAazd+SXrSQ=Gf;fb#5r&vr zazPZ;ue$@(QPXR+{LYM$TmJ@GX^6inh%##d<6Mr0eP4U zTEa&xn+E#*-77De6QP#TddWl#u2@*btD~W$0bC3Fy^BFJaZ#-HXZn+Sq0I)dTIt4Y z<^X@wS#=6EM;@WMhI%K9`aEQXRmVyGK~ahA z;wJVo`^QWs;*AnAymK-^?!z?+9ovMI6%Co%6lB_g2VVQ9qaUXR-&3Mp8I%o#s$8rN z09=28C3?~rM1?28pMQ5yvRLI+CnuC$Oi9~}0>6{y!dH5w%n!D_-d6eXrqybmO$HL{L^+aAfsyx+`*2#;vXp~>sRe>AM+pgxyl@;o@uHehG+{jb&Bb!8Gx4aQO z@@-u^HRW5I0TJYl?E-WvRXry+;Ag>{@)hPRah&YTY>mSsM1W!{A(Z|Mq-$+hRPcXW zszn>wJ0S~aw?$1biXX#9f(@ePGL~~ardc-+XQ)OkoF+l|bWehcZ&OT?%OzK*5_lxx zDO0(4V#n$ZH4}`?I^AT~uZ|Gd->F+VM-nOSAN!0FZBfZ@I!{P`Z;vLawhYPiKz)QUUqjJlYLO1A z4_Kv}$8=sAw8?~L=W`cMIRibau~hiNVZP>}#5A>Md`k!smLwS3ALhta6bg!<@QE=5 z6f`ZJVED2x<&Mri+Z1e#%D@%mB_RAQb$0CcxX#Pmg^xA~pLx69aA$w8=6;Osr)fx( zi~OAB%NC!Yd_N8lJXExSZyn!NsU5p_3W#D4GoC05E-YUQe3zX1KG^P5lg!5~u#&b# z0GEB>e#jx((;he)i+olh&XBDvGtHN$kaki>nvm&P>Hs4 zM*`ib{+hM*cAk*m(|dmzzo!W9H({daBzBF<{MO~d&8Ob+*IjUIJ}TGEpkH#PDv!^MZ}->R(TJIc;_jYvoC_RyqTSd#-=zZboB-H<+P$^GOS5 zfMW0ki?Yrwf0=aBPVe!~@P-XlX(FgA5!QG(c0;U!D0eKHwt_8xs;w-}z%%|ysjj#h z?^Uz4{J?!~;u&pP?iXbUSU=z3{3IFB1mm&&01!LG@E~lD!cMe z5&v5!ASFmc?E`=L8d~NGPCEhdhJ{~@fT01hEA~@tf45(I<7@aIx^b7W)WKa8G5TED zJY!G7oqP0Ihjs9?%d|`UCA#~X9fpgk@wAy~bMti#Vd1K_pPeWtI615yMz)D4K|upJx6H4>)oCHp5T_MBYfMh45okc(N$U>E^QBS z%WIgrW<7uGjQ@-nF1q-!cZW2JkNaJ;hwG}I82NQ~T5N<BsSW9IJdF+1&Df35UK0cY8);of6dgJRcCW+ ziTg(5M^;Tv@Q1MOiXDyfpK{~gjBHEquNLfSAAElUh|aMXdvY-IC6Wu}F_#5fKcuZ> zXdJ|UxNPVOe^kl&!XG~@W?oU&l({2$uLX)*r+IJds1>b9l7*JATU998j+mx* zdiRYG#aR*Zo;mieW>(4;6Y;^M;~g3*1QaBR_-@UDexF7c?ZTmUNMH zrhS@be5Q}rtjo&el=r9WJMp)Ik$x-Uutbxi#Hs2Cf6u94QFjl%#U)=gO(Tw~{aO~P zDM+h&G}uWS5(BrD?+lnwV?ijq51Cg@PSF!RW=5n4iI12l zVKF|e;aK})cT$-opP;1`gUD2l6gHP>nJx5_N1;H4@>v&80EVD zf=GtmW`^N2oV(7o?^Ru8HnjIpKIvbD7~@5@M8stygSSzB-z^QDh3t@^l7^iub@flZ#BL3^QJ5GB|X5tCnatai|^Q2l=*EuFHs zV;v*EWZc1dg@$%FpTyvFfp^u3x|1bziO%@(l4UVTC0w%>*4_(aNJCE)a_rc?65emu4#~#%@#RT~!rF%%rJ(3+ooNj| zLkdq1d4ED)Z+JMoviDusNuG_f4MMCmYNjxs&fAo+=wkdp` z+b-s`S70gS9->p%La-Zvnzsc}lA3=gQoxw?3Lg!YIrgS+R}2n_-AjKf$Vrv`DkcQQ z@=%eyq+4F+QS}kIY686UijAnRTVr&6_&zkZ_@iw+zx+f=ZuJA+M@bkPw=LR{qCc)4 zZ|z;y``g@-kKJlkm+qo+njBAhVf2qYDTaOiD<`XE=4@9{`|&esp@Pb&MCUkW)If=C zY?=TEdk*#U!XQmW!McC0Y&bJUi8_B9Xd;$`Y6Cjes5HpMqbULw?ZO+v^qNc~-PTQ6 zS?rz*{>Rt`ar294?T^`0baS&AkfM2gP4whszMIiOf4*CyC|_E3AC)7H1yjzZS83No zj84@d1TWeom8jMI#F9=o3QRK4H0DYCA~&dLdB9s2lu)`NG|qo*O1ks3`&ubwLUqd{ zu{DJ6e#?fx)7m>CbY`j-(Z3Y0<}x-YZ@Y-rZ-l}PA}tOaSCr<18@W|z$Wv3NoAa!k zfPJcoS!Z)1M8j{uZG(rg<%HVx^dio2CY^t~>(ic1lZ|H=+3DuE3y~z25;2YJoG4jp!PnWXG1TEE@BlfuX4@Zh zIfJJa0&0z<<_k9`x-WzFr*&J6)9(FV#gsNCdz|E?@I3vn=LVM6iDt2%>rR1M`*i#`ytYHhM*C7>a?N&FHiqEawK2~c2l=$%+3))a-q}JR$M`zV41v`h*IXw72#^lbNbUe>SqhDL5y?`WJ72lZ9}UG8xh6&sXVAU^Z-qA6CPMYHcQC z3v_=6W%85wXDnooeM%)ZjbZz%xzn0!GWlXbr1$=>p2qEV35m;>q~MvEnWJEI=M<@S zNH0ld=Qc_T6f+RCeH+5A+^`B7Y4BL8T@3kuN9wsfk^m<*Ov4v?obkk5MU8O-g5D{* zXnyzOcgVvd!wr<4!VNj|jkXvk+vswaa%O*B3nBKMD5QB}d79|7ipeEX{K8~$*!)Or zmVHD2`&a>QEa~ccy=rC5xnsf>@9QIJ5_@elcx(c6WK*`I!p_c>?}=+2q(wX@NelbIF^SrA_GpQ8&0T@Ho|%1*W%5S3!Sk zp_uJk8qnzywjZozFIBlTV|U2P)J8>dw3$_V&1Pv>s`7}1xM;Ya%C5S3bv?`IgJ898 ze0Fow@zYqD-iXrW*d@I&2r&o4L#22u>{Lz9=Zna8_x#~-pepB>6RF`_+v(|#!fSpw z8!fwx$z`N*qYvedpkpl5G{;-P#xZ}T#J$WXyRtgKbaG$`A->#L7$+7k>Q4j ziNw2;zh8_uzeVKI6Vfcdff>f1n^v1yH8|}?*$JhzC!%DunIQ|eM6jvycBa<7u{2|Z znds*>3gg;hP(4_N$^CL`5}m2)yPT(g*Vj&2@^fWN9~6=%eJfD@9ixBg?6iL&&sl9_ z;>mGiMW=6-B!#HCb%%|(Q&-}ea$V|59@E48eyn(rMRo2-C&W%CUbt^`a`&K!pv&6N z^Htp|%WsOLzl4Ce-v(^B8o4-acBSmL78czO&1_<^TT~ie``I$Hxm3b2Csi}K zHi)VBom~QT{M89VPi!hGl^h@{L)qv^?f7jp3bK|R)y4c=c=1>fSSNIvaAj;D^M>ZY zDZJWCtwNpxwGF0zNRVjcS3j&W&py0<&wAQoGSP6Y#GQ(QkiN?o*|(*kou$%s$=Ez`^zV@3CSso>?-;cZ9dewiLjsJ`5rOuf|5(#W*Hd+ zzIT4jbR!8O8h0qjb-h}Ph0avQkFPf^y47JQU%#G&Puo|F*qA8u5w8Jhe`s zfOjqsZf^S)PgDA)e^9=FN@uR5im{rN)~^tE9sm1py_EhEqns6AR>0U zyk~^n{>}(T?YtGx@dPqQBWN>3_V$Uap=g4>;9_d-HNn&WmK=YiOP^YRP;&TR-{o}2 z-t129U0}E9=|p$*<2j}o_y~hlqXf~+uu=^Amy1OPa*CtJU9W`C2{rn`YW+3>fUztq z4wGs>KCj%pq&weF2d{#%Iv9ACc?ytV1AS-OU7Ci7^`1IiVK5|{xkATJFkn-ZJcz}_aRUGgE}KBlJr-3WM^*k!vcI@w5y zzNE>}?b{@EPE3FRkfLN89&>SG+SFl_Ea~AFLnx`XmZ454dc3ccLXT}~FQ>l zfWNrHVRV;F35qIQ)5NbA(;+0y*?wJ?P)#me9!z4d(2 zSg1f+QaoMdEDG~Y!P-;`PJ`A__oUQ7Ynq2LwMBUGM!j4zCn#3HVSHY8(;V#i9o?3F=P z)6V-#!OYbz#;DX5ZJ{k+;Vi_7Gk&@rr2y0l-1c9! z5f(635&q=Io))>%h(&DFQkyt^N_zR=_RHanzWSE{FX-Y^2R9(ds$^0Uc>ofxQuf;I z+GcD?YRVz}OC9jQV>w4RJ(Gm2LP&l)i*x;_^-8RBU37Hsiy@jm!VC96kr&t!g00+t z(P%3&!q%7suVciYblEusSzEF-l}O$tP*7|0r_C^+A!pjh1(EfwdnPhELAL;7Nup{z z--e=JR|jLG`KJHY+)KV_NYutbOaIvRD@3igTO}n&qzNeYZ@!w&7xn_Rr-3*c&@U5H zklViK0l0rjfTq)AX^K`$F3GD&KF!I>IL`aV-MIRLkl+VmILsdA#`WuNp|wM ztflkusqd~MKO7FY=|DFSy>8zONVA~?(1n=J=v ziJ>P=4c~K3?7OQC-rR4A=I&IB3n+G>`5wtEzk)Adfp#0BIg!JAmyAn)lt1PS>v8?n4t__JNa#5XzM&g+WQ5=9YD)}nU1STb=eVI{hwvGg4^;x3?L~b=e%zl7 z_b=2Ry_y>+_WQv3i}0sSlSLv*acw%!RCWhFhXcs{;;5oM-X2pyHlb;LBX&J|JA$61 z*+EeL6!6VPBNYt8yoQf3m83)s}m;zFliqaxE-P&ZK=e{h6a-OQu;D?vaBv zeu@!7@CL12>8b7|SZawpvqTge_>Pl#)zUh0s8qq}N(Zxjd51NB5|_;9o_C&GhPtty z6%lZvob`%D%lS4=7Y#aN2qdL8h?fnsiLH0-w9rS?a&*W4jM^>}g7o8q(G<2|Bt&eB z`ooOyM``s%l7#V`$7LbHH;f~-`BB=1-&u_gS4dPf4e044>@{HPSQ*X7&K2nyM$h@MNA{wTizrJH3e8DOiYQ!yb zoy-cFiuScmk)qmaU%SY-l`A+2LbEUK1KIwZsD{wO}K!}lR zGx$9uF-r_b*iR!e7bK;88Yn3{Rv!^yssJP?ZXWYy@uhixp>i5mJ{U{~LI#2EHJ52x(DcYHVz5a=nGzkU#(*?75P8Aa=;*k{I$vtS8~@rz zO<()bnoi;#ps;AErf9Iz9u~#cm}q-YxtorfMW9kjbvo&6PRgmSA>B8h@z|h_8+^x6 zs&&{ZsIX>#hNkxT9bO-kS5JviEf5$V-zz_jr7M3nMJ!3w;4w6zUeOdxD*GnGtYcEA zAiFb;4uLh131eZWEe|Bt6BW{`aflGG$!Er4p}UUK%$wM8VI~T2j{3O@eDOa1{A!3g z`-!mBkav|gGeb8QuAV_?5f5w2HD$O2i~R=6-$xyPPo}cRY_K)&VuvbRP-Q~F6F4<0 zUq)%=hPC*TeJy3Bl~7i`_xnbcc)OW@+b+F`pgB{+OmJmS2nd&p%qxulU^|_5Wkl~H ziZ9ST3?}m86$D?5GhSZZ;FTZhiM5PFtciz!q7z8Vrht2AaS&c|=b=FRPM>Q(9xBuM zDfsArN#@LgWJE;b7cZylnF_c^*WO&9CodVqUQ&Wjopg2@s;YQ;gtq|d6cJc~0nGx3 zN(uw7S6Vlws>wy=aJK_wsJ8ZOA3|!8B$z6@`Ahv$G%yGOxOh{@4w{>?X%Xfu; zZ{xA5Cfey@BF^)j?Y$}rcK~4zSV!L=*}C@CO8S!Wj#0?)!~4Ad-IPtlqk}JTrCIPxfxNVDoa-vSF_X~=0N64xaqNd6pO_!i;nyRtL(Yq_Cb}_$dJ8i`L8q7Xl za^PESF-CbIkv~1Z2eY_ZEc2e=gyW8XHQ|bdlsf2h%Px%J@7Z2Py#6lC;j5A|(===C zeB(%Pw$IzqOSD?!H4*dUAR*Wd<*SZ1C;`9(D!sC7cAIRYI3pD@AgL%UF%9bmtEhpL zftAhchb$7srjlc+-sgtDi7Mk?tL>OLu6YWPNf>>>rNTmF!zRYJ@?RI9FZ)e@y=@y{PttRAQu{9-PZziSWT&g_CdUXRF_AzAUNplUTB;q}_9o_Gy1q zcB8h562i7&5=$IpPF6>Q5##9tH0w{RDgM7<`=$H+td zAvX;g^#@UrZfRuvgmJY62$|jSa{UZxgGCraG_+e)T!S8?*l7YN-549W=NMdLtEnKN zOZ)Xf`uqlYH2~tXDp(@)%+^{VByyp&86-&fG&0qSGXAS;zo7*Srb#w`kfBe{UJr}I zdn1J&j7OjHRGNj;slX=(9Y)V=NE>li99N`n3>q`I=xqOj@vF4SvCME;_T>E|PVZEZ zl$}SlMNA<>3&A!?c5NxsRZeBaw*UQrC3~cCA+*^$W#^C;!lbg$YzQkHTVB`uOMAk~&vg^R{uBkt%D83mzKjVP zXNnUJ3AtmFfXTO&histD3*{_vt}b%IH1V)ca_A$sC%GJ@FDtf74zWn0J_1HZPv_Lk zb8bGVW6Wl~6lWF8V6dsM<3Un~`$&Ql92P>fd?&V-roBL30O`?xtPA}pCk}ExMMUmV zdiW@0YXc@93aO{JrSGp*TCuLuhDKhYRf7D&Bu%q+-wGu55@9FjzRjAqMc8U#hG7;L zdAcuyyOcy*Q>lZKqGs(4~)bZYm0J@f@Cb$YJb$!&81DA_+@gAp8 zwzK{3Jd0!ridtHR&Drk%xJkcLQNU+V&QGxC#vH`d!pU|y)N zwU=gs)}gi8g!~}BgTzS*>9WHPiy!(`KF6)$bz#0d{{~~P1S3nagvWg>kyv;>eQ}b0 zrQrIjgGl#(QR8Atvw%!W%9W*N?LxQ!1I0aV29pSy!JW%-YMOVFqrjSc?Df_&UqsTjas5Wjez$ zy8xS$mC-lyqx&Uv7`8S|*?+XC<--;p@bmKo{1k@jR$=&{2zg_bO3wupp~pjeQp;~D z#2L8b$|JA?3XYq55Ax-<;-=V#3QwO1f{LpPPPRwAbj}q!l8koctgY5v>Cp$LT3PVq zj6PU@EM7?YUy2lXId+Rn67h}ErbqB-;=Rx_u%Z~M>KA#T6^DX{$)r49$o1K&JAEC` zo8G)TH_vG79Vtt}#Z*3KO|sv2HE{HsqB6r^u(4n|>&n>d0^k;oIWbm2vYjE_aRF%+f;#X#W(Ky0IcTbn)D;gsn!&ZH+LY%xeiBIV%IS>*9T{v=hO4kW_zGkpZfB_nR zdtvcbyz#~4AXR*PD3S$#+GIVu1G;UED)%nwPEu0xNP%_Kn;}Xb`aW_sXOpq3vC?Tz zY1Ut;8*{DJ!Nyi5Zs`airL!W*9j;o4kZ-?aSp1OT{k&>51k_9tf0nz`EvsA*y(txl zG+-ALiD2Zbebc3l9aWUVPIH%V_p{`GgV30FlTf9UMU>=RBafZ!D%~;X40osivZTqf zRX?LV2-N=|wF|xpMS%=$l(1r8w8PqL9w=ld9^ZXMGA97lZVs-VeSjg~P0oGD{5IIy z(2?f77T`hvc)l4^lGxdz?2 zo62~s8IN$`-qKop%b<)h$vK9G|VAjz9joaDC`hQrj+xwHT z6BGh4Gnb%%0T#EE9s-9f12Ql*m!N0#F+RGB7unpnw4sx0+@G;uHchFqfZz z0TvN5HVQ9HWo~D5Xfhx%Gch(fmr=k06$CUeF*cKdL??f(cV$$Z+m$u|%B#rT}LLpgHJ04d`wTbok4~ z2yg&8*@2v$-@gGMXMmNHslChl3|znfkiEIBtHoag-tCs)zX>@wf!`zS-hJ<2Dqv?9 zXLBczgA3rjs)~fvKX|%Wo4Wi}+Zpuk27oQ!BQ3z@u79=kx9=V1-RoisvUdi!0Nq{w zs%3u$1XzHa9c)cK-fO>uIXHp-rs3)gvbXvt14e)o(8|=w!WQW4{0{Su{nvE<*(cz? zb#Ln6VC(UBHu&$T|Kb30aR%C2G9$9Fzt=Q(d9Q5+vPWe3Ygc6LEx`ab)_>S7Tpj+? z_XX(m_kd{s+8Mfc5~dblds`2H1<(?aMG1fG@?H`^`@d6}`QIn=0z0dy&E#+!!t7K~Tz5xGtV*u}ujHx}~{ha|Q0RDPtT z>0hI@f&XAD2DY{MSD&nl>HA1T?XBKrVP$6hhY{o~1#$;ksDNC|tpS#%w(s-$+pd3U zZvk|&1=$1Nb^Uv!046q8)_?J7ScA+z+y5m1*FRi9dy9Xi|1Qf!`)2k5`|&C2$7_y6(x=gEKYUtlEd&A}Fbt&O^islCPfru~=UFSog?lheDv ze_#IhuK)A=_s#=>?m%8yqv*t3H{z~Ht4|+hmr=3!hHW~aF^e= z@NK>dljoWc=Eh0>*H({(6Ni_5Ir@X)Zd_ZMt`y*T9=;%7LL$#xDW_=|fwf66cU{@5Sy98i7DQ|n`KI?x*- zFl!4=eo-eL-QUslj|>eCbX~#r>=Q9$$0AS(nBw^+pO7cHc$hfdG?>4_K7QeGfY2Oq zb0_wUVcuD&slL0mQ%u$hG>j6nyDOGZb*(v?t&?_y z`QG2ZKmySamrh;=`=}Y$eIMQA0uwfJc!xO6!^*`{3oFM_S=&MzVbzTlaSXvk22(2U z&KWo2Da6i|JXIJ_XXeYL^ek+ae()98dDC+Y$uAblcLt-I?zwy!FpPg@2De(IQ!WU9 zMHVgD*uLb7KSARc_AQ%VA(wB}llF3R*lg$gl6Z8w3wTyh+gNB6ixrW{S>@RVCBLn-J04QV;?2*aIZ-e9?>o!x`DD6q-1& zf<4gqmi0+eh@>2hqUwJzM$c!p#s$#lg~v=Za+LoLH_g}7gV(o#n+>@GqAnOp{g!){ z`t6u>p1B7{x}M(UNs&_-w1}CU`*Ter&?CTAD5H~jKsnNdsKjx4cC%6037#Y~^7QaC zbBDmE7H@99PgFOJmDc{QSe*gzU6~OYXUxPpGn10I@eH44)jofDfn+$0&Jc_?;=b8V zzs(rRczo}#4HAg6nY)v+kRTL@X0FhZH8wGrb<|A0g?qf~30h<3&HvyMm*srYZi$T0 zYu`04yfSZp^t5#cVfd;Sa}(d>of%iNWyvFrVUF1`4s;Z}dO>1yMgok^YWezc7m{KRQqisLR7kM>MrNR{OnHbt$BX`BJ@jJY%iCTrewPvMR-u1|Pdt;!^`xMoRw^s>TdK8- z++@iC7^zIS`@^#Tr9148ug93TVWnm(#47uBP3<-A(vuLaQHuPOR#wdnIE+2k4Xtr7 z5I|?mTE-!IYL_YhX zWPU9ZvuJ;-i>g%|g>P5shbPs~E5W{ijP4*<#l^V`9rM@~()X}Qb$y}^~Q@a%uGZX0`;OO zVM$J4n*mHktq`*bZi2Wn$bp<%lCJmn0Q3ng1 zJ4@p;WzJo6euslq`1+zaZXQ!rux) z63x6s1~7Q)km3LQ;71S#{IppkkJ6E)Tclgx+14LZj(lm0M5G+xdO*o!DUnYN&vWJE z3Wlqq3^w~UvUKG6B?Q+5b?*5s1UOh^abAB~t0?u+)^zY7S;{A7E^1H~`s4TU@bcOT zECg~bc#7peS)=;+P~T}|UrI30NhU?~@fIb|I*@n-9=umQRpC7?ZFW4E;YKrkYMMqF z@vDk65K0fOO7f|?sCTP#uhm*dR2n_EfT#qD+Y;F})gCIyVvQI3iFPOuXbpTg0qTD$ zruE}#ilP@b-CkNgB`8!AG#}_x?h*^hxv`nt@?1!1lgAkE?xfFOs#H;&2(<12sMWEF zXUWxKS>D6r6(SfSdmBmw5ps~RpZ4nuiucl>_=JOaW#SN?dq#d6)aVtish0)z5M5@q*(q`WnE zx`+CU+e(1~&_ej(FZq~=ZqTP<#J+8?S!~-LjTf?w| zsJ3?;MvjWFaf;0To6gTqQuK6DQ=u!pD#DDV^p!tO`t;CpE~0S&U85rS8;dg#=*HU- z9A%9IV`Q6P)cBI7$NeKx9F~7q@Ho$yCyDu@w!AUh!?N9-Jxq>?%eiHeTH3KxKJ68g zf45X&GwLxei&kYeda!S!(UYxSw24tYz8z=mWk=}iJbw6{tq41ZsKkF&ww+dkkZTqd zlAR{#Y3JH;^#;V>`ao4BGl;13y+_;daqh%Fl8Tf!%5As-rW`WVOta@G;8fPd4vp+W zGKuko(}zkJ-C2;nYP?~c)Lj3v4lK>a3V&&_2ql6PPn4fB%=}tBlipsB={(<$2yp+j zxPcZV#Eev%%9UFRAtZk&6#c@p{QOzuHF$?_cfig6Awa_@M9uivY<6c1w&3%83U9!| zo+drK-BcoOP^z^2a}*%pj`;O$;piDlfN2F2=ckdbJ^YNsv_FY6u2T2tB?U?+NEtk!9`Phk%Etp8*J?4SK!TH-$pOCPKHhCQaH-z7D}ZN}GS!Z@69?3=|t;%g?LG z^eAZzpDSU*>jS7=2|Op@HZFD}VnoQcrNf*TeOXPR+x?{OT=!4_ zUVYIZCSgy=DN*xI#&I3U(e6}6Hy0N5dnOZkLhuSnL8nYWOQk@ntzDS-ee{sZzFS29 z?;vJ0{mW&0l%anHQ+Ve$8(DjAH#~l1J+Lo%Ip8@s&z)|#bYnx&otl!_e^?cSSY0FM zbp$MV9?D7F)RCxp%TxU2#=c7&J|`E>)QYjk;8{2T@R7&)?ROwt6}SMP%7Nmx-24Dt z{^ZvtPl)TzP-BeX*?GL^MK;*(i6!j8Rcid(uZNxCg1vvnl#F>jh9%{frDF0-aL4=sr}C?{M+{Qt&SS;M?#9P zJ6KVsZ3P)9dd-uglm~1lG(eZpezfS6RLt2)zhjNxVimQt`)N&CW6NVX{SK5@jt$XN z8cWk3Fx-E;(5p~Jj!@b{pY+>BgYU9r2fBKbbD1WMZtL8``9mr|;9Uzg7;dA?;t4U5 zJeB;Nb7#g?CdRK@)EmKUsHFEl6ZJe=;xKsd>ZP8HnI4T%4ixeK>@;XDq8$z-Wvg^i zaa0zIyBl=mt<&JRSf%m^FwA)&bb9T6PBnNk#xsADP*5L`!#x<=pi6|;xEOfGK9KC0$lcHgSj5vZ7_{Bp(F9gWb4R&p-{n#A%xJt?oxksv+Lu{C&ls5Y^5Nn^~Hk>Q3 zmO1dWQI#82J}lQ1Bt~igFO?OY+8c+R9Zu~76k0$dYF|wV;{WEE{7goppNfExhQ)tn zFGcSg;7^mDl{Huv^-E7#U&hRY>qRR{p8UfFJinC40eYsG){YF;<*vd$eg*`(r#N4k zh+)so(BqGscAb6sEsVRIO?f|w>@|@k>~Px{DT~Q=NcrSC`X4nd%=lsj1gESFcb)wsuhP5W7{?m zr9!WhcK~bL)i#<_3<1dJo+5upVXbk&MZ&nqDeED1+k6=-Rcf)^g9sgw84W;{akSpZ zgjbp2v~0}8J@Fn#bxHLe1=t3TkK+Wt3l5z%S*OBxGOP8 zl!$KCM|zLmPO$S;8)eu|xJ^RSAm_ky4C4I9L5#EA_0=xHtrQ;qwt;`hZZxBY%!+#u ze@H$)I`Og8QXQuRB95d8#2RPyq+Mv{8TygovOt6yd{R?l(_(pCfDyhtlM2qyfCW;7 zA5pdhZ}EWIIqm53kf(|TPF$X~ZK!O7ub;iNJX5@V!)AKHV?=e0ElEV5G5Br}T!Br1y+C`saQC?4y=hej^+ zZIXn{Dx}prDD(Q!FX+(7`Y$=Z(#TWp`1?e?HRgH3Fhwss2@IvBN8UDcaCl6Sk~=EJ zAi}1R-J`l-7*&cXNL zpe@{E2fl&YFIP7F78nKdT{ho?RaAREDPDRiZu>wVW;_i8;Z@7cE9Epf#1f``ibf{) zFY2V-fuTP(Gem!7uhtoU0-kU6PEfsnP)^w;c4p&#@P<|CKOM;m{oTJ5T-xISU1ozc1B`QJYe z$^D^rLRrxt)3Sx<*1yM+p-tUf-7h^R{}JEGUbf@214a3GORmmj{q5}I$SF`~`qtnxR= zGYP??JIjAV$|Ybha3FUfWen8wx*FoOMYvGSMg~Rfs>dcO6Vzx>@)7vxrd8wKV{f^I z043kL!X6|P^xWZjd9#W+c)NKnBY@p@g$HG-`1TZsc=&7~1qQ|^JcbJgaR$((eD+S5 zefU_?oz()B+>FskKgF@{;n8vU zGa}73516UPO5EoD!$|8asVT*hM6wMZye-;VU1vPB->72sj3yhFezEZlkqWXM-_n0% zZp>`{$;@&{-R9BoN(&Ez{Dh3%OS*61K|#3cW6e?_XN^I7ZX-iD2zdnmr;GY%6uX1)@*4No z!+eYIg59;_F5VK?1W{AkG#x(E`teTQ6TPNceOrNgQ~ATCfz?y z#QYKQb|)p^AXY%GbJpnNs!v45mVk7p7>>>O-goH|4~L6P!=$0hQmB87tR@&bI(ac0 zA>HwzT~_vJW79~_Fez`O6?2VD0Bbpt6FCT2qv-$fb{0pqxw*PSbo`kSb^ScmJmbLu z&U4kPY33zE{IGOrw-_7`_LMg}-jQ|+{pErEy{nDKsd$Y!f(q|f-xLe}=Eq5sj{$hR zie}hF`c-DpqNXEjjn{wKcwa2m*+nv>XSU;T+gk0uqo{A?W(H@V;YRxiB zQ3>{aOX_#B0?f*7kpB!usIwr}=|j}@Fl{!sX1n0a-@~!WueE=P1Ml4Qo#LmrF``Hw z+ywrl4ioozamg*}bWP({Bu?^SH1Y(anLad-b6a9?wVwMpg%PT+#dVbp#oeU+ z;6?9?lp&t~)-%_rvTV`ZAfrOU>fBG?bKdw%5-9~1E`%i$LX1F%X~3gKj|_H2Liksf zE7M0FXcE7nuM~goSF_fy;cw-D?e+43n@!i%9wpe(TN?euFehQ!Jnh6O{FHFwu5uy#IZ0*O$1Q|tYl zRJ&*|5m{#iQM)`+G47m! z_<84K4jMm$dm{BxnL^07;N07>PLuAhp#@L`<@8$ox=7AhzJmpwM7S7XlQpg&HWi~lXZPQ@;s|yPpEIT78j*P`r5P7yIrpesS+f%j zhzE|F%XFHi8qGyK|R@ZbJp2-;CRbj$EEi{T`ysUpPSZGH)s7kWL|3s9g2+&Zhc$@h# z%eGGhzKMyT8q^%Bx7|rXp}&n*;42IYxk)49&8$rL4kG8D+H{?EDh|0|@l_=ER#VHU zepQul3UnAavv@TAHCUwl7B;%>f|LH;F5E;hZ64H*eY z%-erEe`L4KsxTpMSiUSp_cN~LvAjkPgWof&{KmZ;FyNN)W<+`b{3ZNWG> zt>>dJ?OPU{M{!}td(*u;CpIMpm8w)XtUrHo0=cb3p#nTZEqwE0DSwqzI5){={Ytqv zYTMrlx{xvYHdYpvhTCPQT|w}Q9GeLEE>+h4)su(IGU4PkHz5ONUPtwzMEyGhs+X9n zIvv*@p}Hdm1&D{uISqTi`}c4)^?)qd{4czNvq3KM2dKmlvgaAcqf~1vX>GQyv3q}y z#Cku<{?=}IZ3T5#@>j~6Ak^1o5Z=J#Tl&^a6xz|&c7<8X+kspN>^AI(Mw);1`dOJ} zOH1OdHPdIx%02XBtVD(BE$nUN%hA_Q?$j%nntc!|S ziQST-=(*S19`&$RQz8g6gkk9<*<}e0PabKcKAR&KzG{jG-lAbxJxaQm;W%p^ ziEu81m6;7>Fp0nNh!GcTB*b^^#fSBLBXu$0?PtdwvWwuk}VB>%JUNriu zASSAIj?p}C1Q(vWew5;aWJCTEpHa+(6VT&VSp%;*>*j9^k*x0ru=F-8ED#@DVk61OS$FZJ$I+s5HW{6pTWw)xZ$}o)2fIc!?W0vOOj|7cMl!mi z5Hg=$>}IsO@#7V#gJ(v7_O5l@BjUaBVvue;fy;e<70%TplLA#(qW2|CB{mEv)Euz% zgT|qe26jq=?>l}H+be$x9U8*Z!UbB=+w@@RcrBXIc!(|utN+SY#!Pe($_;=tzFD}5 zx}c$*xW9ly761Wh=moH?N+6tk3I_ZkGxqDqiE}SpM$7>E(s}XF$KB zkw$gzIyR@eWhf?lYGc!{_nBCke(@KC+*LtjpmlDw z&$rkSZ`TKP6ms ztt4JDjzSKk!G)^rD@%;B&EJdYR`IPPv)RmA2ZAEpEeX5sLT{mnxlv(<6}PDVpY%ywrAO!7Q|!;W4mO8o{?o_jgQmCuJ=+tn5kfz=ys-% z>C^aAcVf-lfroQ00)h%7ze*pCPKX(V=`W@mX>y9B04wfHAsJ$Bl~1ieDUWmCj`BaG zHyWtg+0~e6kqf3a?U`g_M6Uzv)V2egTl$2S!yQ6TFZMuMT!(y?)%(bwLZJNpIE6$LsV&lU*BCHy5No)_;{+AbGqt zB^1(S^w6YTUD=a(E-0W#9V;Vhf4fT<_<1siE9^5I6sndJ!feb@tD$D{%^o9U*S*1u zF{&si+U|;_qe-h!Rcl?U)_0@KK`!u||dReeO2iUYbd?YSz=*bW@^KqiYdBjnR z7~$znIfs5<@|yw|pEZ+O6v=UFnfnl?8l~jLUM9Q(A zF>S^{eQ6*=>P`-CqfYMW6eQHk9^5h;#Y9CEoX7A9<_QTb?F*Xaj|v&TLJf|(+4`p< zas0<~YUDtRY0bwpN3u#Yj9hos3ge#@B}p00Bw`o4YfKqi@<%6;EW;-{VXe%4rw2|u z_`n>phi!Z-u1D@a8VFde2z7t&q+h4!@uo_odAE6i}-GI5>{xC zBy(w5D3ewi992W0YT6S*q`QjW3C`Zv0sZ!zfF_SfnbS;1NjYgUZW$3aC(S_kuD8$I zJc5W8cPiMM0(gUJdU+*7CO_klnJiquFQ?^=k6$3p)RDAPI4Ctv6-m*eIRS3WR?0UU zW<=X1h9CdrHtlvihy#@xDJ^l=)H zE)sEKTRJ1jHeUh9nbcJgV8ZEeu*i!N%Ff1GoFNl(V`zk!PWr5~u5Ntq(PnrN;pXsL z*JEYSYTj0pHYrP#A07H^gqBh3uXg7WKax(JC8Mb3bL!n8_q%_hJi&1|G#uR8sfZj? zab|->g&GmY;Ky4MuGc;plXxKvH?N?wEuMY0uWR^WLZ0uis(Mc4=bm?hI!*P@MEX05R?;KYzFl9ZElz zId2dR<)L~_aru8B18*;$^gJ%(TjKM%z=g0>d9vRK7pKrS0lW%?K!Zdca0)3Ei{=Ni zMr+?kYfW*tyoszK6=^@OZ>VBp{DZutf4pbmahT)p$1Hp?*t!jRGK$L4@62UB*5ZHp zGfL%9kZ&57tKHg1$cy}p{9Qs>R2pJ`D-%j{0@nt}P)L8#aow5q+YqHUa{};z0(nVL z=gM-&A?h(6*pwk#X~Ynt#US-MXh>|JCrmglDV@Z^-PIlq&%H;$T;GE)Hrz%BNw9WL zq*p|mggK4S;EPYH$Ngzs`|z=j49b3agq$9JuY|aIkW7C9X13eF-UVuggLG0s;9?mT z;m(^qe`|jr<7M1{HofuWjp!%#2hwWkPHADl z-`R9Z$E7Ses76@6ep=aU(LrFGPJkBStysGXT3UbnhB^CvGpEGE71TSvEW%oz_PmSWV5TZOUHy@GJ_`$&Io5i2t;D!l3UK-wC0-RR5v*sw96lL`Q| z5v~ry&SF}7e|w>~5z1=NqtELvh+VeMP}LDKMVt?bOB7O6#t!dGuQugQv-}fx!n$3I ziSImbgOL6;PU5o&lz}>103Grg$u!gD{rHy84w~Qb&;X62Qu;EwTzF#G2l`kWu&;mF zKICJS?85M8d#?1uvkxq*j+{)yk7IVbFx+}B4azdqrU~_b;y`SQ%Y)Prp{Q^PM#U3o zUmeXVLzz$R_D(OMzxT>?W&Y5Ph-Mx}ZH{&lr&DVuAMFF7e$yU{MCrZHh9AFE!)sT>eiMrtet5S zX^^^$PNU-h)ai+eoU7CXZSzrn)}oRaU1%zs1I8E`-~C=#@tLjL7dDz&r;&e|->qMn z4R0!AQnA=oIv+l({;DI!HF1-No)O9b7&<#bUFIrCFFk!Vzru;GLV$AG^}?k&xa$%Z zOgwawA+C!nuADzB`e=?4YZmly{q#L2Q$bo}nA8q&`EoOd7wjMY{kg*6{6e3oC=vy| z=F$%ba%VD~l z{dL8%B2ZYs&GPCe8KQr_FQA7ZQ#rVjiiH_hLIYrQ zf}f%!oS;kZN_TUD96I55D=LkPwV>^~Z&#sQj8q}lL1YFa@m!nzI1*FC3>jYi^@jT; zM8%x;siHCNay@p(5zNnn4n}P@)7!J_PcvabZ|hZS9bx<6{!V|kb(~d9j2+t%yK7ap z6?hYX1uf%adbK%k3{3I$j9>jCu#~4EqHo=yhzOAnGviiNY`VL?Zp&V!Wa=Y-{mG`( z)u&JlF~3?FN28|mL$Xtxuwic~@xp2!Z^Pdl+fjxb$_W#skTm3gAi5saM4Z*fvPigr zVSybizh=5KVA+50(E(O>Rp9++42muL+E8MQ9M4O3Ri9TZzWu?;{I|~~@ij@_sSTQg}F(XD@vV3#KEDvq`5>5e6uME5NZ zoOy{eigh1;tyHdfQYXTPl7>tgLimdI6^}9G^Z4?!%Gbt(g2_nbo-J)s}Ai$x!k;Lv(A6&3(dAvAqKR$ z@D}LU!ZCl;fsp>t_*Q)!{Ga!XM);DVrW~3=V{e#QQK~V_%2khJ;3Y$F=WBie4v#*y zul}hw47Ud_3}c0nclUN+TDHv7x$eRhNr)H8}=yNu8UwjM+$l4=+HpB(sUVq^aW5JIeRKr@! z5%t8pcqhuE1UiKHz(TcVd2X{I(&lbc?;#w1aSIh6=su*}x^q`=fJ6)Uwj%cJyi*vO zh|)8j(dPphHcYCFr&|j&+1kz{ymkR;W9Y+jEn53fs|NQ@85l996$F`?3o(sPkidhg zv=gEf*jv4Sq>HYLN{`9p4@ty=EP3!DQ~gT18lRuifDCD=S0oLeJ@*Xi5hwTJ8M?vg zXp)cQoB5AU;cpE#vvA;)ZmHwZQzm zw^@FFn%TRCIt~wIu$~yw78BXUo~#6$l0~3T{kRkKhx@H`=@2Y79)`s30|R-krWM#T zcRHN5?ujr2^J)OnnC+Ad3B;hPW}bPuQhGIALl>inOQd#sjcCg`>({#2Zb-i%Dtc4r z`U!iJ%9nHw(=14u^HA2Defe5+ogNx-4&Cd2dgvs=&C)qlH?f)fqLF|}IXp%8g5hh> zV)9uo_$T~z=nULIU9k`hZ8XNUQQOH;^oM2S2~TU&K74JZDP)-L;3^i3yeC})Om@V{9zqW*HNPT}!;Pd_it zYY%e~mjK&xi+j9%YhGvM8r{1qWwVaJ;cq2Zx+aZgLPH}h@@I#|Rmx`}@UWo=eyO&Z zq^p>TQzR3TUUT+))Yj0Buo9+;~TmHcX?*pDqyG^v9F)xoR0GF^}HtFAF zxW0N4iL_W2OBhdxkw074%rO_hZX?AZcB)TW=u~FGmK78%2RK^Mc_F*7LRuEVBIziB zIc@nV?c^zs80GALkkQQ9FvT0;&C+Riwx+J<4iH2cEU4%ZocIEfo%%hFkkilpg^hJfOmsGdLq_)VwAd@9` z9rBpF*C2(N7)xO0o^ve%WsHsizp{Ji`1F%^wTyWEQHNiua3j>cbUarLr~Y82ti-YU zoN$5V>)B=r34>``U3>1M(9=QmyzF0s7kGLhF+FIA%^AR zL+$7}_99$?ihnd~E!D6Yc~D`9?Z)iHC?O<&mdC$Lk&Y2{Ix9)WZl!XRk25>Lb$n5N zeWmLI|LNRI%8ss(C-OXBCv2rh@}4NEYTy7BkgT=S=-fNhtHx7*5ufRhrm5Q6Jk^ga zt*-ey*X59lmh**C!BvEcH6m3U(&jxEsRn5+fI1Bj_#HC%V5mK|TII-Eyc<^jD~n6`4?_iB?f-$v<=tj^PR8?t`$Zl>v2(GG*d!w+uC}c|ENE3=~e)8Di-hOrxlpVKu&mH*bi>TnJNnjdt~{H~|)~gbG|)2u1%aiQ)MH z1UcM@%^k;m)m;e{@P;MTD}FyVhOJzp%peY@2@Ta2)Oa2NjiZJuA?J~c0g-0Gfb z$x5$}4|W7&;kWI?61x8n4TtoIU|F9ETr%Z26qOGu{tKuh$Z>B^+@aBaLSO83@&Hmj z1wnyL(2wGMIm_0n*Oauld&CxNu}Xx1g=9v3vpVz+=vUB%9Y zU!>lm3TEVQgB>?2jHr)X?~S_7^?Sr~Gbue+lRrss=R9t$J$?OEN3Epo8ZxZ!7pun? zZrrmijajE4>gPmzoT~GBWi=7_O+NM5Kz5p`US=458*=RW>uj08S1S!u&7u zmF+Rb2gba{pnw4tm#p*w3NxMHKedfvBBpC0Gy{?mPa ztTEO-aZOzFo@4JtPOPXxCuC}G3>3GwbD?9RXXFORTiP1CIxE}T%G-0v(kTPYT>*dP zY_R0yB2GXf7fX9PQ6m>1H$Veu3J?XF0GOEpOn+QlT(IN-5qk$uCrfh+7XYQ2vIZ3m z4eftQ{xJaHlI0 zIe!C;0L~6T6U)DDKo1k3!#^rofCJFU*3#Me?>oTK8DQ>YWasj?2QKyiOFI)ASJQtI z_$xQF|5ri|PWFE-Z2#*1f+^ZNyEvOTSvt4?{zg?475{ghE*3^E|HO8-{Hq4ooBg#k zwKsA7r=)-B{=)p#x)@p7IRjjP9xngHGJggFOf8)qY>Yhr#{LWD;AHu)G+do6?aco( z16qI+(A>z$)CTD6{1@gg_CMYE&pHABOZ7$$4mO_u^0xn%)&I=F(#08QV@40l#QZm= ziOb*E=9YG_4FAlEl%1J9fQj+na#L4_|IoPso&MDz%712t>TeQ8ruKF=o&Zyz8GkH; zyuHickO0d6JC^DH`$+z8p!mOq;QtnS|KG^{uN?g^m-zqnKL1x}aaS7~c_Z7u1Mu%1 z1NggSjO+k^_Y6Q5@Xw;LF>?C<`54(++Iaq-y#A}T2JqkM{vW`kT#Wv z!uB2jZ#pJ+P5>P(+-O~`)%G5zOR&d9~d(gUFLw{AwJe}7f~Kc4?Q z>HQZNF*_4`(|<-s#l^_Z^zXF&Pr*NG6IUmvza;-_0sO7{KhFP}dmzvQXac*wVsF9| zVwI7d>C%9eKRPX{^J9Psd^FUdyjiuRD4@>1-#;T_kE`17qdt_rWtRJ^({uUU;qyqE z`gnW*)8>1B8t``^zAq`&V1E(HHbplF&2bQeemO$sg+`3`^^)u^gf=^)`tkm>lCpl; z2Nc0u0I}Qn#W2bh0N0L_d@Crg)4V1NCsY>fN_N+)jT zo!-6-F}5ItMFGRPlOHWIW&7Ven@6=I`>sGLWMKH?*Q-8HDJ`tCU>qlBzXmz4b zb@!_Aa=L`mviqah4^nstvH?%mte6KBZUSnBX_E+H9#Phai*X|jsL~Ulj|L3pj5cS| zb(%0u0G@8`Xlxy`rkBDfFBv5Ah0*y2XP&CyU z{$8b4X}n60d^ZnO>zyar9Hl9Hpe(sY43CTtO@FO~DQUIlh`(f0scf!jEt@T}ZD3f1 zL8wQgvpVvVn@6w%I@4p3B8w1+BA|`yK@(XN>0aonM1SL@mIMtlip3JtR2kbKB=0~; z5DLt+Kz_pyqND!mDM^8@p!QYt=r^k!i?e~9hb1QKevFXkUHqmw|DY8O4F9E4i4ij6 zpZ%r5LNPo3T1Y(533YvyOyJ5oP_w?#i$8e~e&XRZR9PZpmCa@Dm>QEM1K;sX03 zh%3Rd6*aQKX1|Pd<9tYr%Ke-lIq5a)FhN90cRtD`5X)#1_9&359xJ_^R2vehvAt%g zYOHoka(wOCW~!5Gnbnv$*m;U>wz@tA-{RlgC4VlmTM1@BsqhAzSumJ3x6XZ=WV67* zCL*oyY3Ffp*P>bG8`x;rY?3ql){Qs-b2NvIrlTdr>~IhG`B)K5#_!H`N^&_G=4wu- zgRd-T?+XnoV2|E?T}3DMzrPAPa)OspFlAI)0(+8>1ebF$Xc`~QMMMLL5XMgMOLyeS zrhh#FK4$Z6NnbwrbPm{Bs$Wsex_hsjrfhDTt{;o_ltx11kC+v$JNom@d0(+KiST!nSTJn zgPpruTcD|v@vC9bwyx+KSMp*n0rC&5bMMJurtjbR)2~4&Fa$>sZ%7bf~9wCb$G?2_p1JP;!r?B&G4^? zoV7&0oqQe$(44(hvcV^19P(a;H4FuNIa8!pX*f7AKS_bCUX+Lw+TDk++alJ_m)Z+8 z8b3eeDhb*;c|`FzN6>Tn%=ftcc0prz3VtkbGV2kew*teR~SedLf#QFnRctb9(jb0?LhA7xs)mJ!656q?Wy1X{Pr3A|X9U|pQH4f9R3JSZ>8|ACD;A&0hw1d?AiP9ssVuxs0VUre$)6opM+~wE9 zQ0vnQBBrG(!e|zQ>+QakZroMhf`c%PTW9`_EJz;YhIGVbe}4e$kX`XWp>?U&0k>ma z0BIfDyqB0N!~E6kjCY0j5}f%BqNpsf4h}1qV1-@C>{SA@E#dpxe9wm&NkQ1=8F9w( zD7j@WTz}=xo-II4MlMKG=o=uWNX`{z_?+>Ca99CUA!gk>?&6l2VYv|#BsD}WiwDx> zK!mF9UXRMu)qhs;cNEgbeqSQa0a7b1E626DKS!%nDE>sZ;ec%4=^C6py6{YxTf<3@ z46S7FPgFFWnWGPk>!+V!mSqp(Jg7g=*YhlH(MCpn=*T(c;=J>k2|N#m4PA&iGrk|Z zjfZdEM2VDc_h_VhdJ!#vij{{zD^g2CKEg9|Q8i z!n&wx5r0Cr1$`Pga~7R6W)GfEoJ0#q{tq$)fdNFGk3VeTd~)qro;>^dwKUS}_c!Ps2JgdwTA6LJ|q54LM`A}b3VT%A1mLV)_-t9=s` zHj+mnIJuk0vT4SSK$T-rPe*$O3 zjDIMG+()&ifJSQ5GZqz}+>7!RE+UWe}~qBEL>P zSpEs9MKED0{lJf53C!>B26W)PFHY9e`+w3=m^AC%6lhK=UD292LMK|~lb%>hWOBs< zV!LJ`i(Bk?8xbu91@!uAh1U&hN-am&JywXsOil&Su4#>*$yK)~ckTgD8>%*in-R;K z8PaFK7y_o+r^`ibcpOjs(1Ps+RsYQZ2+y+JbM-%jDA~LOLlFb_P9+kksUptRW`EPd zaJ1vFNk85|2@;2ex|$y4y3fVwvF)I+n(mW`aEtk7Xz}%@dxm^R;C|#Hy@MaAIMsde zh^}c0vfcM3uW^W@)&Nc4hwaBRPSUDeD7I`QeQ!XY%r^B3sx70v}aAjUORG7#^_?zlr?`Jv!4L?6<5KUr%} zc%Ewj0d|CX9|?H{eO*F%(z`r@*(AKQX(^OEehx!lNb8D54E3Y^H7l%CA}%be1=^=x z<*yVcyMmpP2f(*$%9oY%{C{+j?_Z7)`6rfQ%}A9wvN7I^!|>Bp3OECMd&AQaM%Yxn zlPt0;DJCQ_48i;2j^ynZym^7N#-H`U*pBD0&-!1ofh6*OFzlP~Zi^gA=K+14`z5Os z6x$EGOD>&ZDW`rnmUxa8RdTGh;1}w9j(YJ%k{`md!%l+!Al-l9TYqvP8(Nb%i9hCk zcvw~#T-6cI7&hbK$3-BAXTV%S;t%^XO#C|5s-#%ss{0dL9S2fH)_DLewE4(oj0WkA(FN#l5r*QOx!eX@3*m|;w z65E434s+AEG(1+@EvGUk>2Dg)FY-rvVUp#RC##uvpX)3vDw5r$5mmD za}-JwFLU0fbNHaJ>&yWB(IuVsfCGGO7t;lM_ZDUL?hKqO?ig7=JPbj^ny5@ALig*> z+4`ub*&EjO4CC{vDv(~VM>DU%0$$LF`TV1WkAa3oHrWU`Dv?ezV=~g%CK8R}a31!) ztSGfT6o25u>EieW8}XG!Rj{-|M5jN)sy7cWSDj2>SQc4{qo`Z+V%qhSXHXYxeAbZ6 zbCX0WK0FyN=)J^qNPh@=>Z*NyQw@lO6c1mluTV{_Y3QvI6B zE&&os9;GpP5s0y>*^%vI%JD*S*yvdJy_L=GY$x(8*+~IPg$;g z5xPFeME5&4Fu7_r+Y`f^`RO~hNR02brEVarDwRhX-`fvev~iWmt(E%ww2Y3RzM1*I zvCFu!+$sC!uvun0^DZ8I=j4|C+7WI!byb^bH|r`Wkil3Fd+olYQT$Bw@V?;`^d5!` zB!Bpcxul zEm9(eJ&mRZ$YreKNlFm?h&4Li&Pe7P$%>Az7pOGCN5XmVSqF`JK^hhQIgD%S>sfqk zBct7J>+?b=xa?TaI~T5*3##Od0cE3D6o0+J&y{YI*&MJ3WSd$-cD#e96oEdL#2B%l z5jbAMUvxsXo8h476^x<)kyjzNW9N~h~bNan|eMySc7S9&8z)QmL(Yl2D#St0#7kR#Eg6f11k?%YqMt@Zx z@5B}ysfR||Qpacx-|&bl^ne$Fu|^^)GVx11&#g-Gy6bn3-mBtOp#)#$C~l_-sTXyP zjlPhj$qpGW16-kGlRwlWJk_9jm+}Rs1`^d>#EQwvp}Skh-z`ue`7^?kL;{S6eFpDXi!gtiWT88{zax|g%e{`^4#i?HgH`gX z>Jt%kdf7n7T73s#$ZKlQ58OrB4C*LvWX;U|L1!Nc`N@mL7N6`(QZZoB>wiRv0?un_ zAl)gA8}6YV@AIW&;<%9g-U8i$*=Y;dtCSeF?ps8gEKt+#;;FdNMVqW9ryJ6% zxe7rlFX-=6@@z9JTpen=y7GeLr~%<8xp1fIcXLbvaC9b`ZW(%7vE?aVmL7VWUA@2 zn#d^Mbae1v>rN^)nSLwL)X$dhqEomdl1@n5emrUTn4xX7-0iegWIPE^BXF9h#nCm( z^Q1-i1CLJg5)%_JOq+xR>rs>&9SJbe%}`U0;dlb0vkd=!QcO1qAAiP?PKv#;mFU>V zVg~r@Oz9d^l`)hvIv}> zxvB);YU;8)Y8d?NNFyRlk6&*L&=POz%F0|p*&xc_aJ^-)6jPQ>!5|E>_~Yr!ZI3qA zlK2n&<)H#rLPInu`hS~sH_7&A*4-Td^=kOe5g(SkrP*Zea^Xn_FOOEF+{XEsyIYuT z7QP6F6VYy;?}8iazb=>+^w(nB4B8s^TDnxqzg`VBm$^y`Rw{UQcvT|}qcXhjwy^(6jk*V7e z&Jgw6FY#>qe$bEM40Uqfd>neYu%c&V>ii1gEX@8sAG`mY&lCBz87{bP865rGo zl%MG(2*FJR!c+WZ*o7JF}_HZ+SHNsK8(XC&}o z->|7;-(B)i+kdA~OYMTQ7V%D!M6OaUyyIm(TC55KqcG&NS`N7~FABs3%DBpUay)rJ zLeue;4u3l2AXh_-)jBM^-RR~{vI-1I9Qwbw%---)%)uK(0N#EyBK&Iy?gt0T5 zu|!WWsiCg$+iWI6xBT_$61}oueUf{*X)0BRlYiEiaGMx47p6^|A<3^r=Xe+pgK|Cv zl6UmHTLDOn4f^@R!uY0Z)3@vG{iP+|OYl!Ef10q=@f77cwPDtGS%`QE{Cxb4{AqqM z?HE<)2dqQnV-g!+?y@SL#Yh&qSz8Z{?MGdEX3aB-q1Q%^z#EEsW$Q|ybv%|&Yps#s zRDUy%+FLmO&L?GY%#?*?krrsl*>MpfP*lo=&v(cc{9)(lh#*l`anh|pW&UVn-n$q} zY2FfP`SU>WJ0x9V>>MX4&S&t0Ww_m9Xu+8ate4wahfQnCgI8-)|8{L1+bcnBJPU%K zG#{DrmOxkPO^7y;_|aoM18D>mriWV)Gk=b~K$=3d-$H2(Gk+IiXZMD%LsgfTJ^|V0 zu8C4Qy~xooQTcK3NY%FMLaXwq%51CLpb}_a%@~8Bg0`pknsSQg!ufqxx)s$bT|4 zqX;wUzkNBwa?R|9PGNdl40tdYhY(RCF1EEMj#pQyx;L6`#dfrUzD(0?6C0FkI>*xTLBx_wmnMJRO+ytf!!kzf4V_xd*D3nKW%E|dzBLf?AuIR|Esgc_jk$WL!hhwaz`y)7 zb8V;GB&#B-q1TH-qXG&4oigU7ViiAx%9J;QonG$`^vD{l`9A5*JHxvj{EF@5-h!y2 z&qt4mp!zT3Dv0Z2q`In@XnWadzZ%811~ngvcmMdGOp$q~n~CwvB$8J{q@eUgF2egC zcOm@K@g1@@YlU0d8qXFRx_=!0s5gheGf3)mjMP4Lr5z-_-7{XYjX7qkpZE4ZFO278 zX&gMQNc(Uk@>ki8zsbkP(N)uuFBu(d)>oP#pZ|`1kxIL|%hfOszt&8%Xt}s>A>C(( z-)ZupypnF3+u7Mx2=YNC6q4=SnbEvxcMIvx7c}WXMwbtu!7u|?Ab%>B;(x-BThoSD z-*H+^V9l38p3cvea6tdAjpBzF-<1gOCrjO@qSvc**G}h3sZ-k=JFzrb5{g~p4$-M2 zqmZ%I|Gal!Xk4WNxnMjmKw^mTvpcy0I?mB*Zp4^%k^s$Ax-}Z)<+3&Nnsfoku@Aq|&(R)`~_)7RgBedVevPl0DK&Qg?lgn0_c+ zY0-l;E8cw-8xGKlo-R9;F+%(tuNzv+cVKL z)@S;In&%k8qdq96Jp&O=!p1GRCB9|u{s}AmS zzq2!xZM)YCo*UHR6JE#nieVg26tssS|6EPoOU(g|n19^xI4q9%0#-3zD;kj56ED^h znsGnA*~{9pAmkuBtWMQscR8KXzb49YU)kcSap|>-2Ac*v4p8&x4t&OIF^_IYPdb}N z=Y1uRX)By@sEucX@(t6IdQ?+I5xM=CMj8FNVgTOqfNML}#97-%(~)wHj+awHg(g)< zs+3;ouz%RS2_b%{c>}?{JbwtqWlTdkm;*z~;B}nN4I6-ol_Ze%K=yq0ijg3}LD9nV zf=Drd9uoKfg2K(3__+6|2fpFfyFU$c^h$z=@F72^Ba(;r(xy_q&Vd0JTJu0rChJsj z_9bU8&dPfSd(Gy!&adceSnY(E)%OXRwf%-AC` zu&hKp_S~#~oXMjAV3#AL+6&T1s@B*D|9_MWkSnb^-(tetqo`5DmdE6+Or;IA$y!Xn}6Cm zpqlL(U@^%SYLi`9d~WU+6GvE}Gr7rD>)rdlI6n{_QS4ki<5AY{R#g#wFz|XNhrY{6;A?k~tW+}#yv03hn7mCkSqhEK-CPgH zrt5G+{jqJ9h$Dgp=dqJo$(W!ZM}Gn2?j3M9IZDgNjsO}jDwOvQ0@)p}5~$#_hbXIy zNbP=tp$%TDuM;xN?oP-XVC#RiB@(_ZpR)Y6S&^*Yk~@#j7w@l|+jV#gJ|+iJyDR5i z1KXG-6_=2vsE#Hz(&k^>@YQG;XK8}{>j_0G`a`v{>s4{1%*mHG6g{pcFMozp++acu zN9%U&mn|eniRZ=1bh|AUr|q*9(K>|!dX)fiS+85$#lux;wG7hw{n>PKW*Yxnry6yS z0($L2juCfQ&hdfhXQox$NS1DLW7>fUjgnzA-> z4-yTvt`!50KlpIon68;6c7LBye8Ej%=i{4*DFjT&F4|6>qKHwmjDGb8my5EIC2xG4 zO}d;Mr)bs!o;4Un9TCrPYJzowNT6BpK*#k(u&l3ndrFDpd2G@J+&D+(MDed*$k zTA!)vc`NuPZRl3{rhkg|8r!=rCeWcpX#FCEQ1FAV=qXw%ISdm|X5pQ509A%S-h7vr z_;y~YZX4yvVDDD0I!O*p@yq&`R??d5+zwg&_*FnkAMNr97ev%mFVv@J*Lj2PoKE0+ z&Y~PTt-VP)3;W$HO2~<~C(Iim!CY!~Ad0GJG?Hf0a{m@bC4cb(={o}yCo%gXXinIa za^+ODqGPaZ6?^-D`mI5+pS#tC8Hm&@K{X9mRy)WJ ziaU=fTXh8V@S^|?I9s!ReD3FA4Z0P@DhiiW2>wP z7b(j|^w_gHOoT1=qS0PM9!cRx@WOx73M7F@pAVw7R7u~M_p!aiwrmoL1^C2C3@vmnp45NC&-U|A&- zUcEj53p1-N5MC9)My^P^s8(<2XX#}DS^p~1l2d=ptsh19(6`*2(LiPM+{{lqfPaL7e3M^bEQbJx$jbI_HR- z_ROt4&=J@~N+@8}7&D_tcK7ddk4-TA>}5oe(>ylLSES*EznD==UMWEd?)MMBcPzx( zHc*ic;);}>9rp92-92`95Vja55pO!EryfC%Xdi~72}ef^v82aZjpyk3qHO0p`}GvXU&IGSRy zuXT>0zePB>+m$>{qxpvQFjcMPjNQcc4=$J8T&-YdYrD*i&G~VRAm#>Ykj|}#K=_?(H0uHQjW_P}BA`W3!=%E#L$}1H_SrCNrT0mzE z=LyxZ;&FsX=NL=rGI++BS;*d%vl;A6+A%Wbn;WoY>D!{k9X1hnju#L zkD*QY;&MMmee|Y{8Y_xWuM-IBsZd^Who|%H;sr_LiEdbfQsB4$VSz6n>+5J&kthqm z@_z1)MXh?=MtB!=7ei}SCW?*_F=g2|t|uPjh1}IVmrZb{+3nt@zmg0VT7Q^et(4&B z$aRolNwC#dX|d6Zem(_SXgk*Tw}lss8`5zEXDJ;9BaXKQTFfOwyJq( zd`Y>GOAFUf;#6+rWD8Zy`Z`}V`)!-TJKlo8gr!Lh5EfN`S-OyyznJZ(nXPIgSWoagtL>cs5P0Qck}K}Jgat2jnjlY zhZG8VbIqJj`$!6L{P{&C8|ZvWqZs8fwnNCAzMDK%_IrDL`aQ zCO7&FTf_(U!wm>(Td;2ahB7||s1wqf{&MHb(tk4c?IA+RE^7(mjqNNqx$R;J+f(Wu z9D9$}?c<};f?DPqHS(mvbV8`B5e-VTby-{s1br|TYp8oY6-N*77Hoc9x`x1+JZO@5 zW_2<>5zsFz6ljX5|9^}mmkJ#vNGX;(oOL%LSZoe>Sa9d5Y=`i_Nmn1Hf6R-Vw`_h$4$ly*C_D)Uk|Aft82KUfb6B+sv24Y^x6^BUtIk z=r!3cHy3X1>Y~+{!hyc%@ZfLppCI&%qedrmB0H3s4x3j?bmy|?uUWy^Ydol!0mgwIZhoZQ~C)pH&{So#AFarwSQ8JD24=Qsf=o}7)%Pt2j-!# zmePrd$*dok3}QpjZt&;f0)*4CDRFTlr%i;%#qKRLG{Q^CfkfC{Ssl`vs|wi=<+mYw z7}kJb>{ts#v8iLewQ;9nIxPJO-WMl4ubD$~-9jqLKO&4BCq#jU7T*Y%HCgI5(grqS zn0}^dFB1>fJ%wtvF1bG#r7WAGdu9jg1(r0>o|7j*bM7U)&`>g)y6QpGY;A?3oZ#L_{Q?c-%97>k&RLaq zUGS{7spfpvY01|WglE#xYLgOHuv)_#A<7g97)5zEfbjapo~YubNXFIOpn}4!h4KzY zvVT@>hcSvqQ~JAmnMSXNK>bhN=`Bshw(=HahZofNF^+QB5oM~OG)^3)KFQRq5^cq|=0Xl36+5lfM*Hbi4aJ$IY=uS}`YCRS zNM`CVANXxcscm=H*P3FTQQFbpTCOw{dwK=nGpl@Rr%JZA?%`=A zja9s_7|?b(%UxFEqaQzvdna+?s*)V)q9GdE1EIi5Q)+6Zx0wWk^sXqy#rfu@z#rvF z4jP4)7p8m6W{=DzhMrE|p3SPSon{zYm1Xo5qsz1Vp!(N#cPVg5Pwnk;-l@#_7N`5Bi(v(tv@y~mVMa80fqs3{X$>4 zEwWguLKK3!eQNkUzvZ_~Wu)gUB}zVNIfv;B9>{aR!RJ1zV+d482u3#Vn0bM4sEh7} z3gkcnk}&c4r1TW(lZ?}~jh|_!9C|smcNs4sYxun5GCNONzh$9Ex5f?FyMGZkN9etr z9W-K9hYf@nlRKF)1g43(+-bS$jbOn?p=bq(^5ZS?3wlbSbxpjL|4;fomuWJy-J8@D zM4In98S9}7s#&Sy0q)`?(udDpu z|M9&-`2_N?Rg_Ol6Ovh0*Dw-|MblhnVj2OKqU+?{_3fS)0>c;BEXj$)XNHPqvZ!bV zZSvck>FvFfWsBwFsY-4oaqC<)kvRbqu(JaR3<+&m0>jX$jqsK10)OB;i2FuJLEewD z#hL&CIA;$zwHNI#JQX#y^${iU%(cX|nrMFbo#t`f+U7tb(!e5e(rvEUks#4Xo3U(r zJ;#q%|Zl7pBExb(;B7`vCw?bIE{5fr97w- zp!R0iQv1>6d|2q4!hf;W-YRF(eAbJ6*wev1MU~%h7N*5}?<|b8K26?R+0!gm0l34x1+duwQ@g?D2fRo{v9*V zhNEK5BF^^;Odf_91hl`1>sfrYaf}eGR8(95qKRAE@N$!vjejG{P(Pc~L68iZ*1*4` z#*&MDkD!*v==^A&c`4JsW)*9tR6HO^*?c}1Z=z)xW z@ux&-#kS-M=YOJ54s7vs8z|IQ&}TL=5XsZK)*zwYWc*%PqH@=ARFG-0EskK(;AHGC zJ@I{i5L3PmVLP@zu(4^KGF>YBDcQfeot1-k?UlGEX3hp0H$qQ1sx5Xz?{(qW&Vp{9 z1QLFhnQOG6R-=q=#peT(1EM_(U3%iAJqbHh4SzLrSAV?NIg4Q*MolwEm#IyUj_&u( z#_P03Iy+Fjnd^G8P8mV0k^)k67OR;y@6(V#xL(I;{iM-$%e)Cy&Uc*SuoYANpZ8lw z(^w3qZ9GE6Gic>yK%fD*bb7dA_&Rqv9(3{{7?5)<3b=a)ASq>^l^|ca8RMv!k-zad zrhX}@pno*mz$VtF2GPQQ5;b9Ksq(eqmoq^P4(KS3=GJWl(K^){L6qF$#UD`ArPPVS zi}+8)3y&}`t-cmi5I5j8p@5$ve$P-Z)Q1Vk%hAXzy|F;;I_hP_+Dgn&Wv$lM5WH|( z^&Uj%c4A{bDQiZlgoeNcn;KGH7fkM=qw#T~%KJmdpRUfI(Kqe>%PMT} zD^mH^ez}gg(S071>F#&zq)EAcF}(u8vj{C&nU6^Olx14*3)2)w0Y|>gCOm6{kCARjEOqAE?clXO4Vlib~SS z*1rU|3MKG>r9^JPEt7gBK#+nY=kCH*lYcdF%P>-Xoi_@-zgyY;G@~>}#dBeLd}L2t zn~{+S{dqkPv5!qkeLqh@g|paS^6hmkuH=OuDJQn?IpuqrpTZLUw&99YYF5z%JVh0U zZ_j6m+n+>a5pS*u2Z?^;%hm&JSn>2pmZ1?P{I ztq0Nx_n58z3{g!x4zirA!Vk4TARW#&E1ybV0y51s_!r!j*f|Str^DXRgEyoh(x51` zXVzp3%ur`0f6WzMJE^E=(3BE&nSVTnEmSQJA_M2qhBu;iaMcuAw|h;J9D!`3&2A=^ z-3RUD1>If_q^`xw^PTQgrnV;Glkab3HG|bF1(xxpXo+ty(2F5a@=mn(r@yjT0t`DB z%mTl%KAN6;pxbBN9ds_~tu9Y90Ut7}VV?`)j=8ke^WIx*a{a=*%6m>T&0z(>8_+mKYT5?ManFP@_ty}!+_*1vEN#Z(Ec_wybKxHz(iYSfP)n3 zRwWU1SgvqMnH02v&Fxju9aGu*Qu9KdL%kCHk^pKzmA@=HGb-H3RL)0e)QS&%#R4xS zO@o^MFi>e;ZVMpKS=mn8!xrd%nNfdLE_tzV)=~fv4X+`ey7icZgZd+R%;fEdMFfAX zQF6wD8aZN>VUB0@60=IUc~2KojtPW(x=yj*@rr3&eL!r*9D7q>N`I&E-f8YHh%`b2 zy&Sigc)DE+^t!#xbsd2`9s{ljNa}7ki8taDX-h=n|0J9)l(hZWBYx_gzqo&|1EQJ% z!DqM~HK9FCX6d-gQr-LVf+D?#<;N+VgaW=HhOT4luhoGN~M8XnH}wu-i7^KwQ1UHM|K ze)MrI$G%&z8O>?MU@0Qht}?0kDgC3>c(jOGb&BVz67+DldOURmwt-Mno#-x5O&td8ICQ$0!zAapDG2n%5wBs zI@XGbW2ym+RKmuZ2Wo$ab#B3cKS$-t2>Pj_I@!hRpYq}zFEo`oBL3CyL<36m4279F z9dUdoyf9C>37DsMjVh-nJz8VUzKEfITIH%7^M-sB4;0o%1ZDQVGLyYJ-!De+xYW@K zi24u3K?(6-vG7KS&oWG29i(0Z#Fbq586Pu=S5a^bGS4;4QHg(P_Dr*_*<-%{aJ^u* zOqyS}?2N3ZVWN{A^?)?JcVqLrNWBdDbwz=%U_N|4^eUg62$LX54;Cj;6ft!(XFvA6 z&9{nOv!hm1L?_3qA29Q{~Hj31UJ5EGf$gjSDJU}-pfH*x&y`c#BxEe(MaQcDIGE&cCaeyo@5 z4ad5JSO>Tzhb8TR;*_6*$$jpNq;h=~J6kb!qSZu=$pR*uMuVr@fE}~8qcffB8=9wI(58MxS=#~#QUJI6$l#7_fGxeLm*Ju& zSA|~#=S^fjeablrEAHAxYJzmdAQ;|@J2&V=QRMoMi`UE@;s{rW-S?M4d7-OJjJ@0C z&b5Fn6H&i*sdh9Vkl$PEXF1OKg9^kQkwnDM05DI0hsZN|GV0-suG2mQe8* zw_n>X(OQPqH+9$eR|{XCyxQRduh&Bgtdb2a)c8|=jzq1yG&Yv5O_c5h^#t&=1QK!I z)sR~3o3UWDFfM4DW<;u}VojFNZ1fhK22hJ`89@aoHAmNQC*zD5G4N%}T7h%>B(r~! zMwdWRcZ&9K>Z)h7IPEWXT2MD~=Mx7{G(ai?1mXU`J?iq|D)tF>BFkSJqfvWhJ1mCt zq4$}U<0ctCftK)cpvDWo0GteK%99(0!H&~0g(G;O+;|IX zUe~}sk{CC04KFUg8uKnd=gkDk1Xh13G#&*z42?xyYHYh%!e9XSPs8LP7)iwMIwaO| zI&>US8N`;2YY(O<1I<4=`jNwaIYG+XcS)Y5ebZ~`kvq8ZRnf$zETZ(9gTncjQE-$ z5$Dt?_O(~dK_Y29#SOQr2o(#C31^v_TbmP|cVF7WYi;wH3hc8Zn16DD&8HwM7-hgo zTVyb&$jjB)pNV{PpA*p@yCW<`0xp4)cVBedm!ZqtZ^$w%`6GNxzheeQ<5>00H4l84f;O7af1t1cKMz{wf&u zzj%x=Tf&Yd-=0a$0f*N z&}>!^T@w_Z$K_;Jr({c4`BiijAz8uHdzH{gaF802M^3J@2rYkh^I;d9d^UTF%FeA& z8X8W*IS^iHW6pH&SJaN}Jr8FK=yy7l(L{tLn*^tE4qW7@v-8j4~fp~|s>`oZB z=yi9*tY^f^u~&cADSscXJ1A~VYXv`@F6icW;{wIc;b88?wX%b0%|p9QBIyLfqV3#DumM2VpB^*tzcA5|$Uh#`SBjPe2ng^Q@C*ST8sM>C50@WfYRCwpJ|I*Xq1wbS! z@xiGG*k6Cn3KRS+Cb^R)Lswu1)lxMECHXe&4|@2gUElp8!8^aek6W5f4tnTY^Z^wEGAfa zr+3v!e#swAV(}0Y==!A%#!M>nTKCR(m6x~%7`qrYQKBERcK2@$wdeMCx(pq+@QM00 zfU_HG@!dW5M#&S{Lj}4lE1|D+R8{Iu zy2_d~=^%JYLHIoceIQb|S_Fnl@Dpj_C~r1r8Ncqexd{1UBRL$vm!+83e^kNY##}o( zor7ek&Y0HzIQP$o_G))@k26su(4m@|?t_1G)7Um}E}$eshP9_I=<95%QrXKPWYvby z`C69{L+m~6Twb_G1J)^j7#nc{;Pp35np)y-j5w?49TZmP*-&^R#Xr(ma2K9x4j|+) z;>4?8`R%`ZoKvq;2!!(>`sgb^F{KYe&rn8e1aPu86gNLJOLkTXZce7H0O)gQ9wC4E z6DY>K{&c{9z=jZJ(q1L>9>o~-!LhKUF7w3R$8eMciIkq}dZN+kY|w{NA_>X|vkg zI=N-oih8Y+mKmYyUK$3UZ@O~b5G8MVTCFRjOako!poGYAT~bB+7&4bURZ*qYy*xn> zXSg1ps#2CWYVzOT9~Wvw56)U%P*bsUZxD6SLFj)#W4`Y8A98cDIQw1B`!RpVRNyxX zyb&w)%qsTGgcYF!jXYpEC`RxKmb)FpVykOMBx2E?t?f#89IN8o#F0^Ie_>8Y1AHZ$ z|D*^YAP1w|N5Mzb!*FVpoqDKYX6R4_ZVG#+I?O2ELfLZRq9)WZA@8XcD zfK&e5VOEfkVr{JbA8(H}UNSVojwPaTMu1#A{2csp$a%JUm_}XXUx+CB(sut^o?qcR zJ79%Oppvz!2q5q^)K)^En8N4_Q)CGkS9N>HT%}LAA`^5KsN6UsH zv>X6S=q(li&qy=~Y>V%ZS2#?CSJfG{OUuZP?%S-?z}6EKZV-Pgb%@7?9@RI(WU^W4 zW6>r)rxQ%4+2rW`DDd_<2r0%Y^Tu+g(=^M#OCT9tZFm|vx!uFpqQg`4Kh~!8QNF%f z&0#iWFMkUPr93V)2_ln#^>1~ii5S_{!Lp4k6k-ehwo2(gn|2mLC&uSn_5^^WV5&_J z1WUS@HxapBAeMiTCDMQkL#A21z!09qB)CLhW>D~$S(%U)3opGw(6?_!_od$Nu!WNW zPo_rF0>55LY3YcV^o*!-!5pu#Hc@C+kp{?XmQNWQH!zpb>&5d1g@DjHOVxB;g1o41 zidj52eU6D@B+kWO%sxK4fbrg=WK3Rl1Nx>J5=RC)(@uZE$1K0BXh78*JkDJiI$*{( z>@Fwb5~_$@0ix8*dcu+gtjJVu>!F|3Q%1`?^B3UAND?gKavk_L;&gQB zWON^YgTo?b#;-Vm(BYqMdz0g;XK_Cbkh$9&$4qOq4Ylt~106|{H0d34yf;aGt#SU? zF-w%q0uD%_!4Pan4t88g@Ti49RW?MdaIds~S@M78Z@u*&Ew)MzEvFejC~q5NCA?F% z?v7)H!+0ywnBCm1QIYtIWFCM^AjvFSj^#u^TQhd3GqgVA4znj~@hDt{F92OY)Oai} zsQ?n9{9>A+YyA?y25w-}RCjKzkhfdlbGZO?9`+B-#L;!S4)!UmWsP=4F)}t}sMKjZ zCfa}UOKLXa&Yap3nEb=A&j_V^kAtw>qFT0bS9R0P%q4|Nxyg{v8hepq&rkzn#toi_ z=|6Z*Ho)RE#5};UP8{_jHcS==`z%fPa+N?r)8MrVxi;Qvt1HhTIPB%-6CfQ{S*( zxN@yTI_w~V3p~;XwbQ*hON-eyLYV$RyRg73!G&eT8c$AsK*+%qEgq)wuv|i8=SQU1~v}x*npJ+@nBLF`4)=oM$Z=TpQmf{+_(H8;#NRb zY7jQ-Oc&{@m69G%;<35+{w|vw{@&11()y#CWf1o0emhNd=y~eU_^U+9{akjAD4pN9 z8`e;CS4S~b@RtEdE~;|*oS@$Khhu*)nh*fuUWys5wpIBMEu1{uL!i_^%~qJUruy~6 zBK25c<*G;yOtOx z?~bm%g+7gto~hMtZZ@f*VO_`?n}33QEe@#}y_gRk7Z32R4hm&%WOHYvo$s4}X3igbU(c$0)m>HVu2t9bP>?98G6MEKvbaeFpY58Xhz{LAMkiVX;)|L(c z%D)dD=5~%w_T~<5e<}X29aYWE0d7|201In7bAYI#lD4#hB!F5{K^-7z?qKfnw+JP7 z6FX~DfSk3dxr3`Y4ZyUUCFJDd_;-i>U+gcL zlB27etEr2%lN;b~R3$Nqf9L6DW$gA(Y**{QFu>8`?@lvEQ}=&L`WN<><}d1IY=7*8fVw-PPK`@;@`62e_D98oQX;nY+6FrTNSK z&*}VUoq+$XdSfRiJMVvaJN|3e|H{GI&DGq_f)S3H%7Oxu5LR{Gl&Zff36=79ehNmJg@?0+r(p%M{s^aA)YFmrGN z7+5%ge=p&VT*=J)>-_J3bQ%>TKTH+FNe_5$bv8G%4%z~BG>`2FWf|G&_PJD56} z{nJOPZpIE~e_QW=8UBGy-CbP%D*mr&@VD~+SpVx1n45cmN;jT1#uMJ~tn&J6u_g*@4`hPf(p*3=8Ws|Tk$yeFbB`p*w{vLFZ2bVt#8pM@8eKx^`tXg>`)~Hq12{YkUA4S}iTTTM-Fn^Nrvsc`vM)K!+8J_L*p#fJtQ| zHg@CeO2~p*IE-8cff=oQ8g7DBlro~f(O3t(RQoS5(nT9kyrMCTnBo8|-Buh-wrx0V z-)X{^_+_yV0Up=_{5qUoQ-2dAX@&DpK26;XXHXN2-G6LEesK8coSL#o(yO%J9ber{ zDhxaW_tI3UL^zoUSbQ7?ox&iIr#iX|AV+jd%_kDwfBLCFqt!}dX6#4BhWcyzVEq0# ztuRUu1bW||6r*{|dm?hpQunAni063MQc|5{jRMQlSE-&SqXp*i6>8<*jw<68-_9VDNnB}l$)oVi4eAy z$okeAV7}e(V|1lco!q*oS{B2*8sGg;rB)7$ffLMcE#1_B_@-&FBWqpwbRg*zRLou| z9~No?LC`GM+p6hnVMNs&zJUcv{T27ecR5b?yMORJ9Te2rKL?}ts$HGUfak35p(B%- zNec}ov(@Z%Xpyu%JLIf7h^Nh}dQ#UT7C$B*nILn*eGADs(yRbrPml|1z);eEcvep5T zTz@v=hv(zQMl9-5&g(@|fcN|C!@;{eJrl>Jy3QdKoWQ2MF#vQ*YjQ7*BV zFRD;;KVUYz%p((bj{5swg^r3Te}<(=-+wkHQi5!4$rkLf3jm_T$c^}PgfBZ&;h39I z3VEk6`U;E4t3JVyBah5UK(4A$BOQ(8VhmKunkg1^VQg%5;{;n4Bi^tbFW;1xHN8P| zEMvzy-oY%mXFx7WgkD;Q3L(o5Wx{;HG6XJ-%4@Uc zdSE(o-2#%zPVC!_%KW+r1Gx(5+kdizAoHTL!CYVYjWUdaI6bs7&?K(F{X^H@zHxi zp=fCvLwOS9X=)eh*w+BjYoG_};9KOqTWkLawo0fqOfpjlkjPJi% zvY!a@RLdzs;*vor;oLZv@P9e66Sq|bTbGjdqQgJV&RF!|at#95>~n5L_j9;FQ!8UZ zE2ng{cFa_J<6XC|iUa_Tq!S+)VjfsiSx4s39@whMWGQ(b)Up=84;8Xa<7Mw< zJMG+fLQ-3!wn!Ku_fDrCAxH8O#WRZhnq!aQg0D%`!QqMT9W8b!nM3h+VCer`x;%M@ z94f^)|15+3m04mCn3jnGABsu;nDjdtPl1=*auj!6J}`=uCpyBG>m&qzQ%h~kqh_cE zDbaHsKHLPMYWJfYFMq|F1`c;^5F=E;);=huk=2oCq)I6MFgo+9VI_VyxA#^62E0y& z8>{cSVt^Q$SZ$ZVu&bT&-O1*)>Y$_C#x~Xavb0YNG|UDAj06yk z^9D9glb;PC81&iem13~TwIrx6?2A-M+paRq!#R&J`EISeXn%%%gSVy8tg3Ws4KgfK z9}_`MND-d4ttXapz)6)O-@bVoyRT{wd~53W*o>zbM1M}4l8-fOEyC{(&sf|;N2@JU z5k4YzcT|?k-r#7olO7&9>OB!nwG1QlJDFn^14U%)e{Waa(03T}dq(S0z;p|90(g2O zRL7pvqnE5CiGSCIsQ~OQ#@rJ?b2WP5JVJ7d7h<&%EYBA?%o>~78L%K*bk&vqD3f*i zQG=*TX7B{F(YV{j*m7?~rFsj>Uevl6nnUirDB6V`r*j_sj(*t0wnTS8rU1{62FGrA zjHL~bC=FjbtP|pU+kIE3U<^Hh66NUbwc_Si(uhYgdPobx=$Y1|2kQv6I6VewcuWiG z^DnrKFMkDjeVP)7MM~-jtoAO4d9!@eB}7H)wDnlG8EM?x&JRbC)!M0H(+Ghqiig2IEc6lDD z%K=(aqq}HVZAJeL-xj|Y@c!toMx=s)aGr98TY1P`mq^+>kfFE=8dSua*HGut3I_+R zpg}{eqc{9j9z(Tv8OqXwjATG ziKmcL9+(a7(HYo93o?W{Z1+g^!5ZG@ajR@C$to{-ma(CX?CcdL`O1i0z$I+oIRX3p zNQ4d!JYR_rz2?R4ATWcSjT1|uz4cyEnZ-4> zrJp4Q9 z*r3k0f9+I(g2R4cCx#`hHFmuQj!o$a;~_ghDxv;Nce<&@Z9d1(R_i?0<`ZwbYm032 z7{x~~<;;U8*THl?ooo?oxPrN`lwu}N;vo?~l2)A;B{D5AsAki9{KF;anSYuxUT(dm z)iYl5Hr&gZPOU>7o!)?fYcQQ3T=3ZZ;Oi8e@m!Wz7Q>{R@=f*r#<4h1`_)*i2RMj~ z*JBQYX_D(|pKFr5X#86TJgO!UTy}>ewB6N>lZ&YK5C5SPrW}ovippt*lW`ZL zPli`a;bS+Nam(Ph?;n~cw0|s)`ZpU!aEgQV@XYG|v+GxFg`}+m##3i>U`AG)&Ay6U zy)4T726@#`J2s4n*>4-vTTEii_xVYJg~Rtk^WBkgsSatT7RDXU=cF|G^;dJPddNwA z+f%L@-FBnGa!z=JGF5LSWGDfGH?Xy_RaQnSe%*8??g&`?Qxh`G{eP+HeSPCrTvYjd z*z5}<(tW=QJiQges}|VHR1t?+8lJ1b%{ZPq9#<96iDL_c7s7LAkx76Y)nJ{_AHp+1 zlWl6fPeca8I}VFHbT1yX5V;MoZ;jqd1FO=vv)_VNKUaQOq9_b0UL%0a?c(F)7`%h{ zBGcDiZ*+s)zj?%h(tmrd%)n9qCY(-5NhPoX8aN;{t@IChkQtFXgFMDxcut$5q-C?P z&1e2(Pbt}+pLNi~y#6@yhCvgPb3~S}zJl{p(6M^hc78X?%>XWWtuf*huP=VlcI+NF z)FTByE3vrxUg$3DN`GK5vVn~H77i+2t_2nl@ZnWc*ZKc;et)fOEeS|ww=tqjW)EJq zxtLwC7iaI@+ZO{ugSTFVL`B6z=+3x}2_mNY?!L{;&j2%MXTWGa_MJPX=)gozRwI``n<<)))`p#M#42rzIns83--A69HrD4RsoAB1-+XU)g zFveeg{?_g#oLkJbQT+ZRXH)~P;BXu-Zu*JqV?k4*$%4ZY2&^Cb0c&K4}C&`nMR6lWJEpi?BPqg(O)c8_At2%8=e7MJ)t(pik5`YfqR zGJoraYrg=4)3oX_nU9Tg?ngkY7^AiNet+Xx#kp+~G`=YTTH=-Bjg##Z*a`A*QO-ai z3eEF@z7AkAuC-~q)PjL?oEmjB?OLiV$LT&nvr<`%AP9C@L>Zf`>WX-vJ)pwA3fFs1 zrkO|OM}xkKLivppCy@w5S01(eIZ>)MJ4)!J*aqaPY~B_HX~P^=D#vyq!4k!F;(yZb zv;6Pysd`m-LUik-HAb+k9#FqGkbOa(V6KT%#7NnYMAvcL$d+TR5_{aZG?B>97R7Wf zohGUsg=e}iita&aro86px0dpC;txp7Wl|cKz|*O`SGav|e@DzRJ5ac;BJ_wUZ4`Gz z?0#2-1_ovvI?ex>Hqh#ekE@gO-+$@L<;s07j9%`sm(+W)`)o>$kaO~0GV%$ld-@8aFEZRC%?*Jf1MWB!n#fjw1QaC6yr-ZIr@w9+lxW!=RT)C7 zutKJtn-LEGwW~i&@A_~y9Di3v<0!-;JUiscvlJ7uuYq6PU!xD*_c!dEKOp9h%pICX z-CYL-#J(m!YviH$S>@Cv`{6Tgl(}Xu51gUOY!DNMq^OjfU+qP)1?U>#rz1BYR47#<}kcaDS3Z$xbYOuV5gQ*HBRG@*cd@6t~cF{5;~?u1ZEgX%im*mkedY z(uNdmY!FEzjE#Y>P&Ty00TzyRl?(KN+Bdc z?ai2w9GmM3Z`c`XGz!P&Bfhepf86T2o8h-cm#(M}3j1f%Wq*zZjn5h|tIoG5A|$tR z^+Qc74h$7k6!mYOZTS^{;G;CsLHe(hN}}0Sw#u$qx6~=0e@=V_3*oC^9Ri`T_CV(xT!atlYQ4dV~&@@?d9|EC*NO@ zO}``1GVU(l(t_ncKCX&bQ~$ba}hg94Wlk6FkgxS+o&_dQNb zzMXF_n99d>Os;77!?cWzc3|~{e(ZpQR+ixW#D2HJKrmJp2#!y>u-)Qh)jsL>q?|f{ z?LdHlHjPg%CHBv&su@M|ml>{vxWQaqbBJ`=`|9Npf?{1izmKK}_p5Lh6|pOG_;CSS zqrb-Jt$(BpR|u1A2zkIlJmp-%51!N6?4ijq9=>uY-@8m0v0WeI2T4D}X+o-$gm2|r z`nAq49aF@G9Y1ViCO0Oi!y%~qZf!I~~w^1m9SI6xgDzWlfuGGo# zMUkP(@|KsM-lzvxJAKun09c#7&~=g^$`rfu7JCs%dG_r7GBWftdJPmnb{X@Jlx32O z5Pt@vQ|#1nEColZ07mezj1cAN4yN$8b1<73n$6p2s^<_%nO3)vpLmo-b`lCHM;JO| z=l9-lPe$^_zmAFXyLV!6Z8=?w1yppklmzZj+{j zXN<%uaJ4QhA)SeTS?nFZj1iv5)E$j z<)V$Slg|omb%X;8)$$|y-7C(>m-Op)LC>N@_Fr3@SrUWQh8fqqsIWmRnNF6N2DqGP zrCK4y(~FI7{R4Vsvf)Cc!ZOm@I)5p)7aTmgPYWwQWW+HvCslE2y4NJfk19z$4rzmm zk!rAEc_U$sOhGNUY6hVa z(q>m72vy5n|C+p{`&y3#4=b~IjrlmNy@(nj7`)*TD*h{p&Z;|I08*I}Y>G>6(rw4Z^!FWc5>Ddt)}a$FMJN3$u67ad`}PQ0=^aWRVKY2t z&48^99`h6`7Mw93Pv9b_oqvu~HYJ2*pbhM5NGa_qd`+O?T)9Ul)_!_AL5pw`liej8 z0j0{P#uJAR<5l-d59fJtVJC)W1e(zOjSa&uC7eu2me0v8*o-Iuws)q1UBt!=$^@3( zpBoS1#kK!{tjiL(O-bQb0v$U{0IlRsoSzSZdFu!F==7zW)XygrK!0I%@k;BV9P+by zLw4)kuJHW{hv`1n1~yACm)*v0S7Na>&6+67v^;GS%Yp<)jlUv+I8Z|1lb0SrD5+K=kx2m8%q_!Dp>v9$HTTkVvBk^A`bW9Aom2W;wh~e# zw+tAFWH^X6J=2{A`hQ|$ja3k?jh3xwo9fDw_e9H?dod8^Tfa=ZWaJ=Zo*OTDM7Rcu zmMGr@$m%o@T=oiW0^qqQSIw)K-~P*y660Xyi^vYE6MgW!Wl60$p}VXy!G5dnsa5wy zvp(e2(Mj_#!bw?81?{#QQqU_Bw&+v_Qia1OUm~fiTso{YKYt>$vvJzppU6+jsk?W{ z5q|tDb0yJ4SLH>ych(p(OlZR@==S|-?W1E1#?p@Rg351XzE!f`(`h2|NqQ26-6^5L z1tY*ZeXEUYtkLNFD@vv~vum0!sI%_HE8Bl%Zf!|^P$iTN(I#UUjlJ{uVsp(Q;Le^d zA%>hw;GMCuu75plMcIflRj;Cok;AzAM>d~s^lI)C?((o2NTukQ7&$QJfQR7y{Vs3J z_{gn1na$bDU#&|!q@(Xt#?7%JH}p{ziJpkPn~6l%K1 zdMPvuitx+?)N*@TTkmcQpIlytN9)R4(nWAG(gv?FK_`(zHiBtLJh<|$_O+7GVkPI5P^ zg;KkUNPi&}a+Lc%R6tj18=E+t(Q>L>NpdoHCR|QlY5`Y3gaO>x*35^P*98C7 zqd^^|z$mc&!KOItgV(9zUjWL6K(n^+_Fc9#X zddIcpz#>+5P6mUqJp99WnU-##Z}V3>{c~IC3V#7Uid_&yS6oX45|4%a>-Qg$k;&l) z53XfCxQA=lJ5C$%GmEF8!ug1tIjZ#q*{DR6RFri1r7U{juWVWCeeFgTKA~2toc?3FYJ`a0wP^2&@vb z6eciz??!YP!`QtpVqr&*dR3wln$%62UmKN?6*GHyX0-y~{8lFLqI~WXs~aMBIi!XZ z=o21q|>6qKoSYz2S-w=PiTzKaXId($Z9G)@IKp?{k=Bl0s%8c=}9(p>%7~ zmw`?`I2eg>u?Ay*xf4NAc3cL)CEeY~mcu45lJSfALxc`4@(Hy#3cfwINxA-p8-Ji; z|5ay#;1U3zfqeZ(gW54UB(~gusbk7^rjIB0!hG&*I!h9lvl=qC{w4^c21%oEaX&VS zn?3R!xwo%oMX+RJER1^EgmugZU*hLd9D%>A-Vmp^6*>n%S7~W8>x%@rjK^*_H~duIOkRBFg+|(P&bJab8f3-V|^CReBO4mchyPa)0KIDcfNc zXY(9)TRZjmj1C?u66Q{~jKx(m<6qNg0}T(2D1K3QD)}gV?u19e(;GP4k&W^q93Py? zD$iA(e&{oC{a#`{^psu(b-aFG;)F&M|KS-nO*I6+3atnGLghS^@U1Uo_$44MP4GEY zikp>vv2 zxWlX^DHu-{)KZ}@4hK&iXz=cD+y2oYP>LNvhjx5g51wnJ+-fKr*?&k3Mcs(Oyr;{B zEbAath3&hcf(x1*4q7@R51oo!NF3?^?$|_T*T3N-#&Xi_%3M@0Mlku~Ip35w15k|CT+DLW|!JW}b5jJ!)P* zj}t0OU8I*a7#iw1#I8{BhOx;j(!a8j4eTs$kWCm^Hc=PmL4Tv3WDMxz+jVcanUFME zn8&#IU?)%pl-RjgK&KA`{1SP;_23-@<>b|UH@ZRTfI>bp`C%OZT|$nt$=nyT%#R@G z@$w08A2y7bNiXH@grCRj3&HfAWdP)H&$rP)8w>ROD<$yWYrmIKJGDd_xp4{@E`-hc zfNW|b=SHa|g@5)tyeDPpW!2Cvw4u&$Qab$aM}nqz70A&^Ni+MqeDkj=jCdtfNNK5j z3*I5ktk$$Cg{er#BH7`_2x$P)Vy!=f{HBQ@nape{XX9_5q8Vf=Fh0> zNEP%j2M_97+cCY<$IjL)V|S?(Z%0yPmjAq7<-$A45PxLFPnU+1R$d6_BTJ(9YfOJz zkARyJFMfWg1XtMhUPo2-Wya?sE^n3_!p)fQM!@h^hJ!7~_CKT((IO}}ZQ$-_nWsIj z5|;-Bh5Hr-)TfutsPXxl-rsQ9e%qh7erCnv){Z)j`Y3U^a=Z(*2=!IWn109+d)#}x z785`va(_B*DAXU}(_&%W${iXj{!~dvpL4ds95BLMTzG-rYs<`R`+mxHCWOKiu{-B6 zf8Th4vvP38);wBvEV{Jc!jjM8959lcYhDJ%TEmyijeRUTxz?sJW$t~(*NqzTRD{Nl zaGdrr5QcbSb>yqITCL}-BCuvI9#+@;`W2V-co{NghwKoUq-+sUy=;lO{JY6kHrhM{b4qZY;|i6q78}j>oJP> z+}NYW3|`N|>teN1Bp8h}0UsQEkVpd|F|ReVY$l||}>bEip z<9uUt7R5Dn*Un)xeMVPC2mXW8FMq0mG&;Oht?t#COQC`UC;$6K%oo^3tfWoN*s_ud zQ~7S=hro(qP9mf~cc^X376Yi=dOCM2`#sn3Asn|rj{A1=pmL3)(0m$7J|BCzQ#NOr z#LWF*%NutM3kkUKJUvgZtFKtzIuu8@y71;yQDY8d({<|TR|bi#w}W&xu78h7BygrY zZ_X&TWpqdNM2o4#1t@2fGOufhmuGR%6sfREfjMK+)Y?CocfsYgvW7>A;VJftmC@y{ zy7Rw+$bm@;HskOkiL>hsth4kgcn^}O+6b{f71NLeFGD9%vM)F9X$i!=Sz|+phWlXB zfB1LDaL*`t$`H;gkpa$Rn1Af**OmPU$Z;iAMGni+;SAV9nuK>2j=1y%S_cjn_I->) zz^_6#9Oeh2Z`Ym_ox`1?Qbz;W8lQVMU22NwH~y`PYWD}NzdUUI^NQsDj; zA{on9pVW*ZtTeJ-5(!qTc+Y}aZ(u@N%ob{VdLsD2<8wh88`UEOV1@>tQCJBOPjU4;M%jS`9Gm*K3|6Ynhmu~G$ z3Vh&p7aa!CCzQbo;(zdJe@KuCegU(^0epH?qwA+!=qva_$29yht4m4So*nJdiWQ0U zQI82|e++NNH&j0z58R20U}t3-5N$~+G(+VtjG(NFWv0!%t=OpK^Gq|3jkHqq<+C7% zIA$3OIcKxUZL3~c=rjZ?RMF#ac46Hs9*8sbAr|o6m^PfmAb$i{itpUbO2ZGoV`fFt zzl-DfO)b=7IfdwgnXx@oc*$%uHKzFEN1yn$@DdV@jdFV7mXR@+t=BJJP^+rFb;6>|U zcGx@kXEL7&=H9p6R_^{gkyeo1lX2&z}f|xHWNT<2L=V@EdS7 z#Z#2OF}cW_{w`}Bvn{8sdDKTBI!K)q3?#= zt#C3JSybi9MAnhkt8@Cjz3Z}0*ayJ;wo^IDJ*hbtgfdOLkFb05IPI9^@x8SMik{gi z>C*D(%3(>XS^Y5EBkQnlEU8xU&X&^k)J-w@j7}Szi<3}K!*>d-zvAbP;5mfQdLcHC z-V44{cS_))l>xPbld%fdt&~&-*yydZ5R}3dir|MoC1-VU&V{`4F3No=jST=9YL8i) zlSWAT$iQK86Dk%e2l+dD7{(dr8`hocj4aa@qD4jCL#elT6l;1Jm6Svm0@qa=whg5l z*zr!vs0gj36-$cbYI*!tgvrvc>=RNgkXlI~J?~DC))ow|pP^z&KD(i1tfS%gP@dBI zSH{9D5z@=9G^1(BW|nV|lcGSII;C1p-UcLTj}PtBcm2&v!9a6oNYfYlpXZ>=yJE0N zJn_44xF$ho80U($s;Ea>y|YHU_=H@f%@pALmSk;c6_PX1$LXyEBqvfjtqx9(KN@7v z@X`()L`N7>7etUuLObRZ`YM?}%^vdtv9DQpC*`;q^?Fv1P}v-uTN!?!gMCp zMa69HBXwZe8aDdB#NAx(zFFeBX1WSJG{W7ecl;^kPGTAOoyUtmzvf}FC#ay1hL$#t zef$PF*~8vKtD^qE(D{R2&h~1G^c{O*Ud2na@TmtD2cPyZ>*?6~j zG44toMutyN)qqKrqJZ_{YksX>xXxeDykal9P&G801pOuu;>Q4BhFaK;!S-e!`4x@J zIK<_)GVq``k_;l3aKlwVCRalJnB4nby^68Z=iO~!W?fMa(9p_Oe!YOhuN6rDl0Fc? z^osG5@wJUm1orEdU>8h=@4Q5;rUrDIf%zXEIMqk|0#OwJgksk`QHoBVAcMF&)LW4i zYgvf=v);^*KOxTv%~ncc^ca?B*^NBo$uCz)nK4Q_+?~AM<&EjhNQTzxiJ1a zvBo-G0ao29L;$X&Sk%z)t{08x#y(s`1a2{NG5O$3q71_u2{s50r+?{N`o+C~{{5yN z&(DM25IbieOH2K{L0YD|GrdC;$L~86-)drH8Sw_^y9Zqf<9@67{myt3yK}%;c!zdd zA_1mb7pW;huP23RSbyurMg^Y5!`=nROt(E}sq9d}Hn$V;d1zTGRg8C*FN=G`xx@MM zE2sgxD}M(mLWRa>lE0db^QJm`kewC(i#!=~_>vRwCu!0j$Aq%C*@_|JJHOlpfj;$a z4kip=Sq_qPO<~uxy;OC+$;>41%vH7{Lu4CHGPj2)oYwu#Fdfbqe*%Lwj25 zqiON`L_|n~D0gIVzBs)i``-_^+#YE=i+<(2${bp!YuGCAakLrQ`en%lM?~u@Np%2O zt0~BYxE5E=v&CV7+pl>z8hYz+XHQogV+-2T&xLuxhjdS-{@gi5NHhs#c<6gg+^nZ7 zA*|>2Yr$KB6+a#=1Ukg91&OqX9(#h6vxC+5U&0w}#4`nVTKm~baFDb%F^siM!c@#P zF7!ae;qt#)3G{YWCmkxfPDCLARYY$*#+ zmaBE5vn#DRz^WgZhf;C4#?)__Q^^(5dx?DoQKRuG9b&piEH_}o>S)6F^h*ZC=onrdh}TC)TP*bS&Y45Zr6nVif_8Z z+>=vEo&_6e_hGfg9<)Svfn?tTnkMUo-PJjWIDeXf$)hGRy@@H$(~JV{6AyzVv(P_w zctgrJEg*GrP@j7?_8a4VYQC@VC_of7??rPW@M)_1rq?RyL{}j>{e17gowb;Ca(KDm z^_|e777p?k@+0AcN)+bia;{6rdqq~p+VA95o34jm&F8Xy$o1=eiV`pe=L)6%w)1C* zk1i`w*xquoNxX#T`y^=?x!jF z@A~tCzK+@BwL=W(Y8u$aqUYld1L)q&Cb0C851)d}Ax~Z38XZ4#aiUw!Qjtf(V@tAYJ!E1uibe_ z)#%Oout0Wi&~f7qn3iM%V{nKo9vz$;J*QQpsuo@G1ueslFK4~@P)dyO6^frZfAQp@ zWuXYeNi?XA$0O#~cR5`J2)s_3q~Z3{a1J*9PLoQ$EyRZW<#N8Y1KrnQ_rav?R{;74!8g2CEebEGau1pzWUMlta`!6aDj=-CMX6 zg<)m|fjv}wKfqWT!9qe=RVNh!7GB|GM87N2kV!da7?eCsoAxP9p3jf#0M3n(WqPr9 z)FrXcNT5Zp`twK%IY=BTnH&`OP}Rhu#JQ9WLaP}{?<|5%MzB!L61qtVY)>3RDzSbKnDS|N zpJhZX$E0v2`)NO9!cR|AfZzznM&%L z#O;2!aG|HKt9^oomGq&u?LK~|3aj!u`yv8rKrgfi`2k`?leD5Lqou~dygfqrZte3t z2-lZb#^keKaq7J)QfHX5C@l}cU)vs?UGpy7hk)J`QK34|o;O;XMcw5rP%~&cGSl3V z9$PFZzY}dlm@ihlhrNB+y@ieW=ro&ny;8!ndMueuYdj{ez0h+1VB7zhm~Ef*De4@~`$&kj57L}GL$Ke%1u<)OZZ ztk#7b!&AaT+U>=y+UD-^TVGG2ue0kAz_jQWSbS5Cw5vtasgYeCG9<;S)SfkmRyZFB zFuHXV;Y^f?n0Xq#Opg*V;m0uc_EocafovlvMz|gQ?qgRg#{wCfTY${k;j5KoFzSFe znVr&*x*+6O`Ia@dhK*yqYU*^gUpa&4_5KZfk_DlXM`uPPB+GU=%#dq+gi3}7I4eDy zd3RH4l>RWI6x;Xu)#7WDX@5p88s?_CPvZEU8q-#!o!Rs~GEmDU>bIa*QRzyYwa!bi z1PM`-$Z~f64hVIkmn`^7uY7^_s6~$oq z>)_v8-J3U>YPxW-7;&2_o9z#N1JRgheaxLf$cB>W>W_yThv>^)=CConAWok(3)=nF zKnKP+Z2R##9-+xg>_(r~vN}cDWogsd9p!z<6HQ_n;&HQ04IIAc*R;@k)4q)~wXl1S z$fG&}FQZ4L;LNzI=eO0Svf_?xQgrjRVLLLC+73E1M-28+s|X6GR)_LQK;usAX|1tH z*`z!t13&kSJo2%Dn0TImzVefw!1xkD33h+{xbvmugeUVWXED!~W?IN`GsY)qh^`c< zkkyr?MB*}d<~j<5RlMK&hU7FOgTp4T2BD*gA$-{awLcvBy%}Ki%`CqxKC8(C&RjSEMu~Szj1%zWT4eJ6S{2mGY;PajA zUW?oDwFkkHzGO&-Wzx`>wI8h*?Y?E?7xp113dYU-?Q3C6dN91OCQwW(F8A`2A)hp9swdD_P zT$p>M_Ai}0Ww?_b{u8A(&~g(soOA*X)Z4+?*={DyGPip30e>xjo%i%JP%=P(K$!8l zl2e>Qrff?lqMMqbuxFH$n1bWn1~$^HE{JpPV}T3LJ!uMED>AF{x3)3Uody&Y$I-(i-NUOy|_6SP_EphA-wUdKEyioxxT#T>j zofFIU^S$IY0HokBp9>ZeIGcV;u@mm!PLi0Plw}S3=wxYs9e>LbTmPa}Jxr>q^U^%U zq6Q8x$=<*!L8Z{+Y{FUQif?{UoAOVyr0YT4#k&d#jy`uBLoW*u8csk2~_om{%NgwPqcg|81MF?03>lC#1WQJ)TG#a4l{mNC2 zVEUM{4m9jv{QB%YL_EvJ1`WN8-4~EZcr2?|ZYB9BCe&ygK>4bmTz+Ss&(>QbV5;R( z!-|&<;_2R6{A^`2Z&2nmL$c;z8@^pKEY8_ac|Gnyqd`{m;c-oz8|xGQI_Hg(b%WCO zQM{BdT}RnqSP|WeD*r@e1gN(Vh0f|#Su{Jz9|*$n+>IZtISZvRYv>~N2rT@pi591U z2`FXu8+f@c{fWyPi?C{7levlYdn!C1ZNm|OP#nB4}Gp{DP)YMIybk)IszK0!0TIlOku3= zwRv#oVrttO(?-PgEI&9aynG6%0%n>U7>DXdIae8*spjGb3$BHiCMem^<49Jll=g1x$dgD?zghrWvuz^qPZEzyiBs*It0G|L>{kye2+#NhTy55$ z>qX#V$iVM=`BRKLN_VA@^;ar4ncfIo?ydTv5I&Z%SiV)O?$rba6sc8AN(3#15O_Sq zXS*)G=E#0uf6&Zr$^s8I{MCVII=}f{(EGOq%fz>7Pvl*2gV7PSk?#Seq+h6Y-n>fn z`0u$?&?<;?!&mo7c1549v(%$sffli){n2+g81Top+CQ1hF&LBsGMJd{uv;t`#10+L z?8So|U?Fs(S=qWbtKgX$F)(c{jTC@2`<>=bjdw|XWl+;dVRe7CVJ)E)@EH0`bg z;J#4OXi4ds^$#G$Z>QW0Y}S~HIWt4j$$%_cGKnzJ;?FE~5qumnqGa04+gXBCzTwWX zH0hO553;>DE0xS4n#Qck;)GEXZcyDyi$6=>V72#&uAUV4yascxB>CQeVql%h=VT1^-?}J>d>We|Z`fy;c`iS@IVhl(3!^0sTU#?aqnm`=s z?_MO)*duYCkCLRH3mdNV9+lUA=8W|DdTA0HhH!W4PDXiGYUHB$m4pB*Qd&Bg7b{v@ z;miSEOgr4+IEbX@;Xs;_;_+}Z5XRgg(77(?%KYU0?(*4GQ zTR|UK2)SRzrm>630u~3KptWsuu(MHJgjLoM=g*cf4*JXsWk8AR7v7W|n`&9I6Dp(8 zWgDC|OT^l%OzLolrV9AkK1GXP{0!JIktk0uhcJn{Y;u|i$!VczA@m>l*$W0jUr!ry zkO;1|2;<}_pfjD~!S#$&Zx4$|DU<1Dq%YYnv@^z(XD?^fZVXi;H=aPS1EcIjlO08; z&lSYNhTkI6L7LOZV><5L(BGYIL?0IW%+TqH1XGUZW)$)~-~&Jz;QZ_i5lUT8Lzo79{=F*bZry3ZhoEs}1-bUym(MVB^(}3@0;Zo;~Cdfom z`&QJgYdTS{YV}!=M2NtZX9hM*&p*w00t+vXekPxPC+n^P(FG*|xoRHz=oKOG90l!; z8O%52+bLK;Ljs^-ms@J3@M!^C+eb9P7MDmzN1T!7aX=;57tb^PY%x)6j76c7yRNzg zk+(+5_IK{@?8!n-4XkR)ZcM(Kbcq=ube>|cGPyybC#jrMBUB#@6?uy91K^vnDOgM2 zIhJRHQ;;GdGP9Hy`Z=)S93txJzTlFknA`*oYFM7COnn1P2drvZtxU{}SVuHr1HVZY z5sQ^ONpJgzbRZ?MtaKJO66~N;ek$dN2aVXkZr&ec*i@34h*!36p~PsR>>|!=#|XYe zIgRBC7W;pVneZfcq_-Qa3UUDZW0K%jhil%kv~i|>mEhb?18FKkr*Ofe<8N!gMG~es ztwJQd3m*i;D(gm?q1t9$^=FSvdS_kH)RoQg3-p{52aMqPT1A4(%ofG6XveEj94T`_ zEo39(mvOWFnRE5{#+x;-*`DN&$WSH~dO+ZAoKt-%$i`k+i}@5=&mAVT6!cGD{dcS0k*S z;=8^T`{c5?Q=z^S_7|8Q77Ue z`j7DPqFJqGM`tXZ#%|4$Z-^vWjf}Hjf=S7|J%x$j^2#>O9HS_|ILBcg^xYiu6+lZILz3eoFIn9Szqs8t&DN-(D}Vb_7n8jXvua@aqqnF$PpPF~M58Y>U+p zU_xg0>Tk{j!}mw0y$1KWl!KTg#tz@!T6}#LC?t)A>e~kXx6IXRd)gDug}SjN=oY3$ zTNr-O&l>p8eN9573zy-p-j!;HIbBg$XZR=0K3$y6{ya50)HlXp$9|ePC%6nxBy&-w zsVgmypHclOa>NZ?ELTTzF9@6fVu>Kpa(+~Qqv$rm0fL7!78El!q%g_@m9@_WseXi+ z2mZ_EwcinA)Q`$;GlgQF%Hf*KX>DvP^kjEVn6Lm<-G~nh+WYok?TtL&(nZj55b1w?)d?svH&*#Fx<=QCZ$=hG2CZjQuqH+4bxxMXbVHxOa zS4-mfvZ&Nw#cNO--&aLooEdv0|JsX#!q3etgZKoQQcZ8YLRL22+4F zHLX10JCPut?hDh}XFhrqc&bhnH3t5|l5KoJ8y5GAwVjt`PtT`Kh+gF8jpoM_G{RS3 zFL%~th3Jly%rWaf6Dfu>7Q$rs2au1|={q)dA%efR@XDOOO}8up3-%Vs@_;<+GgTgc0-_8!VskNFO-d1fq z*{Maj)4sS*SvWw1-n1^1wK_=cV7In!$!#pM<@cI9wa5G?;2 z*U8HJeRyyM5z6A?CT(R&Pc=bN){BDX4Hdm-+@}@^W~;&As#LF);cdeXo~OIbw!~;>NGeEz;&y7>PcZlIo}gBqRKI*V>a0himxSQ%2s&DQMD~P1uUa@K?J)rcsm5Ydaw) zH#I$|^+_jVoJs4--O-gRmiUe5U3t7|!NrkGt7hoP|E1t|yXnBLo^D*6vf_Q}b>gS_61$pMs{#D?M=o=02i+Pv+QMX-BF$ySW9)!jZIIFJo zYb0Ubr`~vWuPPaLBZ;h-l7g14>BF4G?etQDSsC#CeLdcVEx zXtDBmPYS60^k~$qZ?N*rqJ!Z1nj`b`4_+6LlA-UV%_&UJfa=yyG0gmA=aONtQ9s9~ z)mb&r1~GPo>;QsOJcnKx!`Q_axkmT#1giu*MlKh@8s-S+JDW;2{%YFroRpmi2XUI?TV2J)EW}Jjbp@MF5{NH5-)6ml0bHWM1$EYA}h|FYq%~ z5nH1v_r9aKwFJwFhaAO`2&JdZ(eGUMQK~(ImnX^ZWX(K7_7Qe0k*4Y20ww* zA3yI#d9kYP&m}2(&13H*YzbN=^qSyJQ=ao}TvuX498byG4FtFbbySm_bM)SVuFk&L zsAXLa*o`i7ZEZzgjVw0IlX}C%E`;=PN>5%F->s~1N0vW8zwu)_wxb6lp7Pf3&p2$P z*rgbzG<}L?q1e*9e9+`xVWi!kSc{fL4sM^ETn!1J63RxkM}wW$*0WSddM6g)9eBX| zlCl->9w_F_g&cc;zuK#L$-2;j8Cqpf%DMU*-?1-01Fh)C@X6elH&_sYDRx{HCKd!M zcakpyI29T%C-48Z*5vs2S~E~jA)2BAxoy0nFlX7PhEg?`qLT%UVvsTjlcEV)2#E{w zCm6usIv{#=-cxW?&Ujm*$uvD{E#u{7q7q%4QX9s6{EK2y^|^q#2!ZK{EN>&5v3RmN zUqVk;SEqXDN_Uc3U~o#LXpeG#Zn@hS6=HihNnei`J-4*3VV0x`!WYK4 zX{R!_huZB1F{so}a;W;j`hpR5{Q+OgNz2=^rI5F*t+}gRo{^H z`_%jR_OvTi`TVr6rx1AHx~-4k{LYH!D#*N$~<0bA3+zN^< z$d`u`s$e5y3dqJqzlS3GOl7S-VhoiuN&nsN5r3}y5*&tX*faPcgFfvORB#!Uk|FSV zb4L9BdQsi_e0+_{oSCuqx;eiN^3c1XZ3nzUOF-fkBkLc`$6Le9L;xl(?0nO+^vzY} z=g7U%y4SUXkg%e5Fg&DVCe=zm^%i_)N_i&w%EMovYWRI1EIwG1;eHaa8#j~Ec22g* zvnH?V@TQ#K{9B9A$?(`}Wyj0i-Sjat?qk7xbmkiNa+cTg=Xq)W*JUm%-TOZk_QGvo zgLl{GNu!rJat%Sz%~<8LWD3anE1kNn7jh^UWV}BKSWuC zb-b5#>a1ui_!VcOh`xf`5`DE5xR|(0sB{D#?w+g|?{u7@E!q1G1HtNAg-oQolR-E=IWwvdkZs?MwxM(j4S_kYN;6eI^XR|G`R zlMcv}Q&&+v%Z7a1TIbHUTQdtz1@=)^Y!_(`CwUGw1r9625Dq4wmsN6FCO6NUP}P&? z;IW%v-xhL{B+P7vS()rpUt8=A0g!h~4d~$E zRd8@w$rb)oP!TvzikUH0Yht)XQEFp24ciyD{B`y_!L$co5qFaxckLOy`84>q>M#qX zdy%-@1X*frV;vNI^PZ{P?7vhNV z;z*=NJZ<2Yb*FjDogPEMK*GqL8 z{TnOpwNV!1X2;1!Wx~0(NK~m@3WoEb>Ndonr=C)9K!Z8+XZrROi*=8f^@OQMXCQxX z)J@@b2A(9epk`F>ciaX>Re0Revo<0yL{9-iadL+|&)x)oqIq&W-h)f8TozbCp_O=E zn-*c9bC&5JtYPq;5hJn#+G8J%16nH|{2Q!)uqcVQ*@7=kKnO^h_h0urAtbB^pewTq zkVq{=Q5D%x82u8-1+j19J@su6m-Eu47BadSg#A7l6cegNL-X6hu^_r;_v5Enuk*nG z_$fhfA;}c!)QHP}1c!}{)nQVNRc{smG#E3mr?9eP+`9_P$CK58ePSUY;DPn7@e}XD zSdNXHsrWi(KqjzWom&&T;=CMs>xbpWmA&a|=n>EvWVK7&nNx=;CFylM-V>*6`jyQfp)#nj2Ta+P@NrWR|HAYj6NCDzZ7D5U~2n?gTnHw6*?)1pdnjC+uLuQ+3l73 z;ZMf3tcY_(5gZMLmEsrL83)A(Ea*??NE3a$2?HoQtp0meFoF4FVxkDf=?M@eh~{EY zvuO$4$Wy%Zfdn@nE^#&hV)jA>cA8o@&1@_P0eTe#vqbh5=zMm5uzxaWZ<=F?fXG;M zanTXD5?z%CnpD{lh9#Y6K)t`HE(VZv3-D_FRMuWebJ*?clqZuLbVCmQ>e)h1whC%0 z&rzYwu=;Ce@`2@hXqAN+tZC5y-ZS`Q_R&2AzxNnReXF@b-}zva<=9`43ykSE?Rlnk z@o22|)`0H>iVd2>5Xe&ct%6)>&Sh~(Q2!cdWNtW4Busehql8JKf7% zL-i%XvqqYX1pJmHG~Sv)8qSr!h(=_Y1tuWUEyd);k8$D2yZUV?BA`BA!$ZKc71Gv# z4ZCcK3@5dG^xcyw@fIc;Pm7Pu`f_<&6%bbi zBmN!=$sbw!kQ^i|%V+@|pgN)h{%6KXQ-r22?GqXiJ-|axqHZLlCSumM za+}Eumi>_pkn>3t zesB1pt9EKD8_GGICZq}~&I+EY(Ct6VV*EXk z76qU{&~Ny!4&EO&XHCh%ziA2RbnKZ{SyfQt|LB^O5=JaBMSM8e4Hp^+1*&)uRzfnr z8_cT^d?we4;lVp@TXvQ+Uz>`$CG4^?`B#JSHf)X21`;U`EiFL;`CM3&A$Ra`~ZEQLsJ$B(S6Q1bQT3vi;p}l*Q^d-%|bl+ zI6pOYb0HN6J|URte+%VqC_}*6+JuS2Q5zJ{ETmzjWhXkRI)qL2QzIx24E!_EP#@27 zH?VZ4Wx8m4Wpoz7TPtg-A>F@Qn898gjqy2(Tz#m?UT`eW+)r3CKwiv)>I!%uMXgB_ z!jMScirH?{W!N|$d=@K+Luqr{o2H%m!#hM@h{#Q714&AJY_<`7ZUor-)6o&+gTG&D zk5sajv>EMiD;XAAVI;y3r9_*iG!yMnT{aSN#Gxtp>c2F=5eZ$hFO?X*63w1D1EMUX*w2m z29vk==$6X?6dx--w(eE3&w(`C|5S*lWrHEYMZpqUvd8&=T$N{ZZ~a26r(Dk*CILA4Cy@&5+g>+fN_V+KTQo zCsNOi8jVMBN_+5*5)Z@lL`K9@JV+GLMQbLHDGU%J_KcoU(XXS1%RE9(Yha+(? zHvMjFVU}dC0x8JE!o|kQ&cVS=&%#E{!a_}pz^q{Z?TfLC841l7J~kFso{x8;|1FZV zqym`?$;Qk2&k~jZkBtj~S<=eM*@c9SlkLA2vphUJahH~~K)Tk59f1^D>oxrzE*_lQ z&*pt-I4HjZ>;V*${ci`I3y6U}U(pW5--K4>K9we~q6g@QESV^|X`C{+Nw-JXx$K0y z#V>;KM@{-Pq78~Tgzi^l)9)ZtNSP*gj6~7Eh)W0~T^7FbL=s5ok}Wbx8DKkc<)&x5 zs#5Sx3AxXh0nQdgIoCOvS`_<3G$ez#!z=GMi%5om~f6gzG;zbg3Ig>CBGlaDB6 zC29>>qf)adD<}6WVeI7A+#P7-Ps7$NJ~|$?YhdDs1#I(#Qo&Vp#u-y15)wIAg=%eB z>wn}>>@LjOnta8+H%ppaYN-AQuDxs&&RsuRSy|nBK+?~|r!BoQzC5EoTLIVb&CCW? zyIPF#`;cr)UKl0)ZQJ6MX4!tC+V;+K@wSA)idvbWwYK{D-?E0-Q9I?S<)8|gdf6z( zq67srJ)lZS?#Ch{CrAlCUSptwj zDEY4aP0Zt%8F$=D&jY}ktyTOkNs!Aw1fYPSIfG)3MTM81j~*#>tNK{FSV&n&;ncDY zUT(^S)W7JD{;Ex*ydeFD;54$No`m_I!b;6|9eL?HC49ocaKM{j4&eU?kF4V}ekPoWLyNABj`1nPZD^K;I;9Z#|`#36Qr3?Q9_5-jTA z_DUzMIPHPLfoHj=1Lv^41*~?ZA1Uzsd1BBG^<2%o<>(i%~S56NX zuV)Wt>K9gxOQ$bL8Ls@`&Sknm(b3bd%r!Qz&)qQ(#PIt3_aDJI;%YI`J|26Xq;efd zQh=S6*8qW8&C1h^g!SV$0<#v09xDku3F`+})!yFaA1)UO3yCTMvy7d&{Xdu7|8e<+ zL{ET)O_GzFg`1U4LXuZplI;Ulf`vzvmxYDrLwoRYatM+9KZ{`eBlA(!f7({CaIpW& zwt{j|rj&5eVBnJPoM^meHRGvnHKS#fs9A9Q?s|f#Wi{i}F50%i59(X2L_9Qs*cU{K z5NpT~k^uFv5Hw?FvCyxipH$Utw0+BLK?ZtcekAn=TNG3lUX11=mLHRiRb$=}bO> z{Y-ev2QKIgTzBnN$cjmws-{ViWgn5+6302L?tH3#C~9@en!-kw{b)weB;fyc!ddX$ z$TNQFw110(>8piJaMi5hb|4q-vK2!H-P+D^{}`U$A;()Mcf=@OcmsM|&EkTG=?IYC z4zHJQdYe-9fLY(oWjY`ENKd_N99%`vzcs!N-(sGUY+(_R{AWn-qQ0u8-{i=(hrfU8 zHF>_-`A@$At1tM=_l;1-dY~KOk~X{>k+e4G z^!<+=AccHTH>td!8aB9A{I{p?ukJ6uo^=|W-;fG8J)xZym>Uo$3HS_L&~P4ipqmnl zzu1m%$XIi^Tz0CtgJ*Wj^-C&`tJPe>Iu6mBE|#pqoM&b3ADA{Cb6|%?JOSGH;Q|*t zoWus<2~vMSGS;qZVbj{5z8vArsa5QMQ;8llv6rigE*F1)%zuw z@H4!T+Mxr_a@iid`i|kSpGLqbG>WviF;k{?0qBLFzmq5o<9%XzW8b#1wtPe ztI05bCFMbq+MsbL+?NB$I00%9wwptth2nTx2CtyA=ibfV!=}kh#nB>8N7&epORdpE z%+zj9diA|m=f;ebrt|(jo1?{X0mM!fcRl*;JT`)KvpRsL;Mxf zNap=-_%ih~PEnH+>DONz-qP2@Imi^hWkxe!oYRW z1ACq^&H=<)V^pwG2!QNgGp z)f=<^_i91ZU1$A_*X#P$)~S(U>MDH82BSN{$5g3Az3XXlK)B1_<8H?ozash^MDBnU z)#bzr3E^(!0vBitOSJ@J-*a5KK#ev2NQe*FoxsaByWU{-c+;( z0cHXt28|zc2V5XP>Vnm)yMr<+e|eBNBXrs1NGxXm0zxP-sWWo!2P5|q-fs~Y$=V1@ zyh*lfvo9^$G~=q*IX@gLlzLsQteaaLha(dS7`b%;yV}pz+i`Zy{$A%JjZ8uuO_Tjn zl-x@XK0A^l{;o&;_sso$m!X3pa~5Am(ll#N_hw#ZM;d!!4M+SFVHr_%iE0Hb52w$d zi|U`%uKk6hmn|o+vIN0kH_;}t^CaZL6R{Z?by4aHd|}Jfm*a{a$p)?`vv=iwqT^1g zX5D%NIdNk2J9pOBZ+AK?=+7|Zy8qQ^HMyWWO>59Yh2sFB(U*~sM07@SUAEe9mP5+q z{Y6Ocl>&C;;&MS;YcP2K!8XtuQXW#KrX7t|FJU-to$-1sag+`JH(84py_DRA4EqoJ zTL;c16g?g?Z+&G`2d32ZBzHysn2TEBfa*0*UWto^@`t1sUx&ts-xKjs1(o!q~Ok&gUG-x~Cm z>6p%#qnd{S*z>}wJ34qVcfoR`JwSZ*bjlF=dY{Y-!la6Kx ztouDowGg0mX2f%4gj?J(-Y*JWtlllQTo8Ts_oua8Bb+Dn>v4dJ>W1fmFW8{_tYmfE z(Mwoh{6BOUyuO^({P@<||5RkYEohP}!LSzq8d2B41-!uBt{{YW%2fOKR$xY#vpYEJ zJ+m)*j+~_A$KlRbwBxV&HwWSFBE{P?k){A%!L>2?gh_6nba*T_IisX*L@llr>n~%h zgGRc%=?;wX?#NgIa&Aexh!tFJu=oCXUvzSE$>NAqwUpM@t+;-v2xxa{-Sl6Tv$CS3f+ann8bl9rDeH$A56-!Aj z*WU;veSAqKe(-xR_@b12|6Lji51y_4s;0shik-z5>DuVuO6vbKl1AjMC^Z)_Hh!ZQ zR5re4m55@#skEzdm;DWSHwhh4ISm`O3&`i4L<@+|M#8O#m;U!)p991laHBd^cmSAz zO{la0H3$5$P8}XtX9pstPKidS^B%KC2(3+g{r^n`HEg1+1pag&Ch8P-ha&EwzQE1s zRC9+J--Px;U>3dTEB(}k^Z$-ylHdT4g)H+M)!ImZd^>ADIyAz6&@k5m3cnHcM7DIt z|E~o6AK~Sv$1!a)$e8J`suP)%$X*xY+wXeZIb>U?^6cMr(mwv6WMxdun=u;9O_{Cg z&yAWz>dy_D3F^=Fn4Rj)wVS2u%{7@R=*`udz3R?Yn3d_y6`L98&gGdQ>&|7Fwdu^I zn%U~i0f}aWI&-mRquO&3X5QL!!DfuwbAD#4T65lJky>-^W`bIC&by%*EGeZ!=sXAm z8$4-X%N=iY#}(E8UlRIKCoIjBQUR4}tHSCzIwc~Y3-bXgpLlm&m(c1kFLu71UCbyY|DzsB`D;s}%MnU@KE?8R0yE+3r37x>4G zS#IifOBBIpB?ilzAwumdo-A(ezjSvFACe$Yvx{M_A#Y&5`+Ql}GLu(<3uo^?_=oo+ zurU4Z@W=i@l9bLe#Z_-!TwH9ieFj^7cjkr}Z8L;E@`zndFyuui&H=^x58jemv-qGD z60z)c#=S{uzICs^OSyBVB``@oJ6IFJz?~?l)26yXWZJ=^2uAHh(KT(RAEef_mTr(U tJ8;b8=h^js_m4e~&;Q3?(z-|%dU@dVyi{f}9%DlTBTFt-RabvEE&znS7y1AI From 1af16f268be8d74043b5afd6d7ff8184241a3893 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Wed, 31 Oct 2018 22:59:59 +0100 Subject: [PATCH 39/61] Some pep8 refactoring --- README.md | 42 ++++++++++++++++++++--------------------- dataRead.pyx | 2 +- mdfreader/mdf.py | 4 ++-- mdfreader/mdf3reader.py | 2 +- mdfreader/mdf4reader.py | 9 +++++---- mdfreader/mdfreader.py | 24 ++--------------------- 6 files changed, 32 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index cba0b0a..12ee30a 100644 --- a/README.md +++ b/README.md @@ -83,30 +83,30 @@ Command example in ipython: ```python import mdfreader # loads whole mdf file content in yop mdf object. - yop=mdfreader.mdf('NameOfFile') + yop=mdfreader.Mdf('NameOfFile') # you can print file content in ipython with a simple: yop # alternatively, for max speed and smaller memory footprint, read only few channels - yop=mdfreader.mdf('NameOfFile', channelList=['channel1', 'channel2'], convertAfterRead=False) + yop=mdfreader.Mdf('NameOfFile', channelList=['channel1', 'channel2'], convertAfterRead=False) # also possible to keep data compressed for small memory footprint, using Blosc module - yop=mdfreader.mdf('NameOfFile', compression=True) + yop=mdfreader.Mdf('NameOfFile', compression=True) # for interactive file exploration, possible to read the file but not its data to save memory - yop=mdfreader.mdf('NameOfFile', noDataLoading=True) # channel data will be loaded from file if needed + yop=mdfreader.Mdf('NameOfFile', noDataLoading=True) # channel data will be loaded from file if needed # parsing xml metadata from mdf4.x for many channels can take more than just reading data. # You can reduce to minimum metadata reading with below argument (no source information, attachment, etc.) - yop=mdfreader.mdf('NameOfFile', metadata=0) # 0: full, 2: minimal + yop=mdfreader.Mdf('NameOfFile', metadata=0) # 0: full, 2: minimal # only for mdf4.x, you can search for the mdf key of a channel name that can have been recorded by different sources - yop.getChannelName4('channelName', 'source path or name') # returns list of mdf keys + yop.get_channel_name_4('channelName', 'source path or name') # returns list of mdf keys # to yield one channel and keep its content in mdf object - yop.getChannel('channelName') + yop.get_channel('channelName') # to yield one channel numpy array - yop.getChannelData('channelName') + yop.get_channel_data('channelName') # to get file mdf version yop.MDFVersionNumber # to get file structure or attachments, you can create a mdfinfo instance - info=mdfreader.mdfinfo() - info.listChannels('NameOfFile') # returns only the list of channels - info.readinfo('NameOfFile') # complete file structure object + info=mdfreader.MdfInfo() + info.list_channels('NameOfFile') # returns only the list of channels + info.read_info('NameOfFile') # complete file structure object yop.info # same class is stored in mdfreader class # to list channels names after reading yop.keys() @@ -118,22 +118,22 @@ Command example in ipython: # file manipulations yop.resample(0.1) # or - yop.resample(masterChannel='master3') + yop.resample(master_channel='master3') # keep only data between begin and end yop.cut(begin=10, end=15) # export to other file formats : - yop.exporToCSV(sampling=0.01) - yop.exportToNetCDF() - yop.exportToHDF5() - yop.exportToMatlab() - yop.exportToXlsx() + yop.export_to_csv(sampling=0.01) + yop.export_to_NetCDF() + yop.export_to_hdf5() + yop.export_to_matlab() + yop.export_to_xlsx() # converts data groups into pandas dataframes - yop.convertToPandas() + yop.convert_to_pandas() # drops all the channels except the one in argument - yop.keepChannels({'channel1','channel2','channel3'}) + yop.keep_channels({'channel1','channel2','channel3'}) # merge 2 files - yop2=mdfreader.mdf('NameOfFile_2') - yop.mergeMDF(yop2) + yop2=mdfreader.Mdf('NameOfFile_2') + yop.merge_mdf(yop2) # can write mdf file after modifications or creation from scratch # write4 and write3 also allow to convert file versions yop.write('NewNameOfFile') # write in same version as original file after modifications diff --git a/dataRead.pyx b/dataRead.pyx index 80fe39b..a12e0e0 100644 --- a/dataRead.pyx +++ b/dataRead.pyx @@ -38,7 +38,7 @@ def dataRead(bytes tmp, unsigned short bitCount, array : boolean reads an array, not a vector - Return + Returns ------- ndarray of type RecordFormat with numberOfRecords records. Byte order is swapped if necessary to match machine byte order before bits offset and masking diff --git a/mdfreader/mdf.py b/mdfreader/mdf.py index ef7b09c..288c805 100644 --- a/mdfreader/mdf.py +++ b/mdfreader/mdf.py @@ -588,7 +588,7 @@ def add_metadata(self, author='', organisation='', project='', def __str__(self): """representation a mdf_skeleton class data structure - Returns: + Returns ------------ string of mdf class ordered as below master_channel_name @@ -638,7 +638,7 @@ def __str__(self): def copy(self): """copy a mdf class - Returns: + Returns ------------ mdf_skeleton: class instance copy of a mdf_skeleton class diff --git a/mdfreader/mdf3reader.py b/mdfreader/mdf3reader.py index 70f7137..6ee90e6 100644 --- a/mdfreader/mdf3reader.py +++ b/mdfreader/mdf3reader.py @@ -987,7 +987,7 @@ def _get_channel_data3(self, channel_name, raw_data=False): raw_data: bool flag to return non converted data - Returns: + Returns ----------- numpy array converted, if not already done, data corresponding to channel name diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index 3b435df..bf51519 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -1379,7 +1379,7 @@ def _get_channel_data_4(self, channel_name, raw_data=False): raw_data: bool flag to return non converted data - Returns: + Returns ----------- numpy array converted, if not already done, data corresponding to channel name @@ -1389,13 +1389,14 @@ def _get_channel_data_4(self, channel_name, raw_data=False): This method is the safest to get channel data as numpy array from 'data' dict key might contain raw data """ if channel_name in self: - vect = self.get_channel(channel_name)[dataField] - if vect is None: # noDataLoading reading argument flag activated + vector = self.get_channel(channel_name)[dataField] + if vector is None: # noDataLoading reading argument flag activated if self.info.fid is None or (self.info.fid is not None and self.info.fid.closed): (self.info.fid, self.info.fileName, self.info.zipfile) = _open_mdf(self.fileName) self.read4(file_name=None, info=None, channel_list=[channel_name], convert_after_read=False) if not raw_data: - return self._convert_channel_data_4(self.get_channel(channel_name), channel_name, self.convert_tables)[channel_name] + return self._convert_channel_data_4(self.get_channel(channel_name), + channel_name, self.convert_tables)[channel_name] else: return self.get_channel(channel_name)[dataField] else: diff --git a/mdfreader/mdfreader.py b/mdfreader/mdfreader.py index 7b34132..0c7614b 100644 --- a/mdfreader/mdfreader.py +++ b/mdfreader/mdfreader.py @@ -377,7 +377,7 @@ def read(self, file_name=None, multi_processed=False, channel_list=None, convert If you keep convertAfterRead to true, you can set attribute mdf.multiProc to activate channel conversion in multiprocessing. Gain in reading time can be around 30% if file is big and using a lot of float channels - Warning: + Warning ------------ MultiProc use should be avoided when reading several files in a batch, it is not thread safe. You should better multi process instances of mdf rather than using multiproc in mdf class @@ -453,7 +453,7 @@ def get_channel_data(self, channel_name, raw_data=False): raw_data: bool flag to return non converted data - Returns: + Returns ----------- numpy array converted, if not already done, data corresponding to channel name @@ -1262,26 +1262,6 @@ def merge_mdf(self, mdf_class): refill.fill(nan) # fill with NANs self.set_channel_data(channel, hstack((data, refill))) - def copy(self): - """make a shallow copy a mdf class - - Returns: - ------------ - mdf class instance - copy of a mdf class - """ - yop = Mdf() - yop.multiProc = self.multiProc - yop.fileName = self.fileName - yop.masterChannelList = self.masterChannelList - yop.file_metadata = self.file_metadata - yop.MDFVersionNumber = self.MDFVersionNumber - yop.filterChannelNames = self.filterChannelNames - yop.convert_tables = self.convert_tables - for channel in self: - yop[channel] = self[channel] - return yop - def convert_to_pandas(self, sampling=None): """converts mdf data structure into pandas dataframe(s) From aa3c4a880e9c482070a3414f31ba5b4d84a6e168 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Wed, 31 Oct 2018 23:08:51 +0100 Subject: [PATCH 40/61] Some pep8 refactoring --- mdfreader/mdfreader.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mdfreader/mdfreader.py b/mdfreader/mdfreader.py index 0c7614b..53b783f 100644 --- a/mdfreader/mdfreader.py +++ b/mdfreader/mdfreader.py @@ -437,7 +437,7 @@ def write(self, file_name=None, compression=False): split_name[-1] = '.mfx' # do not resave in compressed file file_name = ''.join([split_name[-2], '_New', split_name[-1]]) # makes sure all channels are converted - self.convert_all_channel() + self.convert_all_channels() if self.MDFVersionNumber < 400 and not compression: self.write3(file_name=file_name) else: @@ -471,7 +471,7 @@ def get_channel_data(self, channel_name, raw_data=False): self.set_channel_data(channel_name, None) return vector - def convert_all_channel(self): + def convert_all_channels(self): """Converts all channels from raw data to converted data according to CCBlock information Converted data will take more memory. """ @@ -597,7 +597,7 @@ def interpolate(new_x, x, y): if self: # mdf contains data # must make sure all channels are converted - self.convert_all_channel() + self.convert_all_channels() master_data = None if master_channel is None: # create master channel if not proposed min_time = [] @@ -1235,7 +1235,7 @@ def merge_mdf(self, mdf_class): both classes must have been resampled, otherwise, impossible to know master channel to match create union of both channel lists and fill with Nan for unknown sections in channels """ - self.convert_all_channel() # make sure all channels are converted + self.convert_all_channels() # make sure all channels are converted if not len(list(self.masterChannelList.keys())) == 1: raise Exception('Data not resampled') unioned_list = list(mdf_class.keys()) and list(self.keys()) From 924a05d6f9ce18a69681b2f8a9f528ce01f2e0ec Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Wed, 31 Oct 2018 23:11:20 +0100 Subject: [PATCH 41/61] version 3.0 initialisation --- mdfreader/__init__.py | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mdfreader/__init__.py b/mdfreader/__init__.py index 285619a..d7f5541 100644 --- a/mdfreader/__init__.py +++ b/mdfreader/__init__.py @@ -16,7 +16,7 @@ __author__ = 'Aymeric Rateau (aymeric.rateau@gmail.com)' __copyright__ = 'Copyright (c) 2017 Aymeric Rateau' __license__ = 'GPLV3' -__version__ = "2.8" +__version__ = "3.0" from .mdfreader import Mdf, MdfInfo diff --git a/setup.py b/setup.py index b08f8f0..cd5e655 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ name = 'mdfreader' -version = '2.8' +version = '3.0' description = 'A Measured Data Format file parser' From c3543ac6f9bcb777fcf62bc5f65e14d34657c68c Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Wed, 31 Oct 2018 23:11:51 +0100 Subject: [PATCH 42/61] version 3.0 initialisation --- mdfconverter/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mdfconverter/__init__.py b/mdfconverter/__init__.py index a67a926..29f99ee 100644 --- a/mdfconverter/__init__.py +++ b/mdfconverter/__init__.py @@ -12,4 +12,4 @@ # along with this program. If not, see http://www.gnu.org/licenses. # # ---------------------------------------------------------------------- -__version__ = "2.8" +__version__ = "3.0" From 5a0eaa3f552cbf6b82851e60df3839b8e88796c9 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Thu, 1 Nov 2018 09:51:13 +0100 Subject: [PATCH 43/61] made consitency in attributes naming for file_metadata->fileMetadata and convert_tables->convertTables --- mdfreader/mdf.py | 42 ++++++++++++++++++++--------------------- mdfreader/mdf3reader.py | 20 ++++++++++---------- mdfreader/mdf4reader.py | 8 ++++---- mdfreader/mdfreader.py | 36 +++++++++++++++++------------------ 4 files changed, 53 insertions(+), 53 deletions(-) diff --git a/mdfreader/mdf.py b/mdfreader/mdf.py index 288c805..391a5a2 100644 --- a/mdfreader/mdf.py +++ b/mdfreader/mdf.py @@ -130,18 +130,18 @@ def __init__(self, file_name=None, channel_list=None, convert_after_read=True, # flag to control multiprocessing, default deactivate, # giving priority to mdfconverter self.multiProc = False - self.file_metadata = dict() - self.file_metadata['author'] = '' - self.file_metadata['organisation'] = '' - self.file_metadata['project'] = '' - self.file_metadata['subject'] = '' - self.file_metadata['comment'] = '' - self.file_metadata['time'] = '' - self.file_metadata['date'] = '' + self.fileMetadata = dict() + self.fileMetadata['author'] = '' + self.fileMetadata['organisation'] = '' + self.fileMetadata['project'] = '' + self.fileMetadata['subject'] = '' + self.fileMetadata['comment'] = '' + self.fileMetadata['time'] = '' + self.fileMetadata['date'] = '' self.MDFVersionNumber = 300 self.filterChannelNames = filter_channel_names # by default, do not convert table conversion types, taking lot of time and memory - self.convert_tables = convert_tables + self.convertTables = convert_tables self._pandasframe = False self.info = None self._compression_level = 9 # default compression level @@ -577,13 +577,13 @@ def add_metadata(self, author='', organisation='', project='', ===== All fields are optional, default being empty string """ - self.file_metadata['author'] = author - self.file_metadata['organisation'] = organisation - self.file_metadata['project'] = project - self.file_metadata['subject'] = subject - self.file_metadata['comment'] = comment - self.file_metadata['date'] = date - self.file_metadata['time'] = time + self.fileMetadata['author'] = author + self.fileMetadata['organisation'] = organisation + self.fileMetadata['project'] = project + self.fileMetadata['subject'] = subject + self.fileMetadata['comment'] = comment + self.fileMetadata['date'] = date + self.fileMetadata['time'] = time def __str__(self): """representation a mdf_skeleton class data structure @@ -600,9 +600,9 @@ def __str__(self): output.append('file name : {}\n'.format(self.fileName)) else: output.append('') - for m in self.file_metadata.keys(): - if self.file_metadata[m] is not None: - output.append('{} : {}\n'.format(m, self.file_metadata[m])) + for m in self.fileMetadata.keys(): + if self.fileMetadata[m] is not None: + output.append('{} : {}\n'.format(m, self.fileMetadata[m])) if not self._pandasframe: output.append('\nchannels listed by data groups:\n') for d in self.masterChannelList.keys(): @@ -647,10 +647,10 @@ def copy(self): yop.multiProc = self.multiProc yop.fileName = self.fileName yop.masterChannelList = self.masterChannelList - yop.file_metadata = self.file_metadata + yop.fileMetadata = self.fileMetadata yop.MDFVersionNumber = self.MDFVersionNumber yop.filterChannelNames = self.filterChannelNames - yop.convert_tables = self.convert_tables + yop.convertTables = self.convert_tables for channel in self: yop[channel] = self[channel] return yop diff --git a/mdfreader/mdf3reader.py b/mdfreader/mdf3reader.py index 6ee90e6..918f221 100644 --- a/mdfreader/mdf3reader.py +++ b/mdfreader/mdf3reader.py @@ -1003,7 +1003,7 @@ def _get_channel_data3(self, channel_name, raw_data=False): (self.info.fid, self.info.fileName, zipfile) = _open_mdf(self.fileName) self.read3(file_name=None, info=self.info, channel_list=[channel_name], convert_after_read=False) if not raw_data: - return self._convert3(channel_name, self.convert_tables) + return self._convert3(channel_name, self.convertTables) else: return self.get_channel(channel_name)[dataField] else: @@ -1067,7 +1067,7 @@ def _convert_channel3(self, channel_name): channel_name : str Name of channel """ - self.set_channel_data(channel_name, self._convert3(channel_name, self.convert_tables)) + self.set_channel_data(channel_name, self._convert3(channel_name, self.convertTables)) self.remove_channel_conversion(channel_name) def _convert_all_channel3(self): @@ -1125,32 +1125,32 @@ def write_pointer(f, pointer, value): pointers['HD']['TX'] = 72 pointers['HD']['PR'] = 76 n_data_group = len(self.masterChannelList) - if self.file_metadata['author'] is not None: # Author + if self.fileMetadata['author'] is not None: # Author try: - author = '{:\x00<32.31}'.format(self.file_metadata['author']).encode('latin-1', 'ignore') + author = '{:\x00<32.31}'.format(self.fileMetadata['author']).encode('latin-1', 'ignore') except UnicodeEncodeError: author = b'\x00' * 32 elif os.name == 'posix': author = '{:\x00<32.31}'.format(getlogin()).encode('latin-1') else: author = b'\x00' * 32 - if self.file_metadata['organisation'] is not None: # Organization + if self.fileMetadata['organisation'] is not None: # Organization try: - organization = '{:\x00<32.31}'.format(self.file_metadata['organisation']).encode('latin-1', 'ignore') + organization = '{:\x00<32.31}'.format(self.fileMetadata['organisation']).encode('latin-1', 'ignore') except UnicodeEncodeError: organization = b'\x00' * 32 else: organization = b'\x00' * 32 - if self.file_metadata['project'] is not None: # Project + if self.fileMetadata['project'] is not None: # Project try: - project = '{:\x00<32.31}'.format(self.file_metadata['project']).encode('latin-1', 'ignore') + project = '{:\x00<32.31}'.format(self.fileMetadata['project']).encode('latin-1', 'ignore') except UnicodeEncodeError: project = b'\x00' * 32 else: project = b'\x00' * 32 - if self.file_metadata['subject'] is not None: # Subject + if self.fileMetadata['subject'] is not None: # Subject try: - subject = '{:\x00<32.31}'.format(self.file_metadata['subject']).encode('latin-1', 'ignore') + subject = '{:\x00<32.31}'.format(self.fileMetadata['subject']).encode('latin-1', 'ignore') except UnicodeEncodeError: subject = b'\x00' * 32 else: diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index bf51519..0be48cf 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -1396,7 +1396,7 @@ def _get_channel_data_4(self, channel_name, raw_data=False): self.read4(file_name=None, info=None, channel_list=[channel_name], convert_after_read=False) if not raw_data: return self._convert_channel_data_4(self.get_channel(channel_name), - channel_name, self.convert_tables)[channel_name] + channel_name, self.convertTables)[channel_name] else: return self.get_channel(channel_name)[dataField] else: @@ -1497,7 +1497,7 @@ def _convert_all_channel_4(self): self._convert_channel_4(channelName) else: proc.append(Process(target=self._convert_channel_data_4, - args=(channel, channelName, self.convert_tables, True, Q))) + args=(channel, channelName, self.convertTables, True, Q))) proc[-1].start() for p in proc: L.update(Q.get()) # concatenate results of processes in dict @@ -1547,7 +1547,7 @@ def write4(self, file_name=None, compression=False): blocks['HD']['MD'] = pointer blocks['HD_comment'] = CommentBlock() blocks['HD_comment']['block_start'] = pointer - blocks['HD_comment'].load(self.file_metadata, 'HD') + blocks['HD_comment'].load(self.fileMetadata, 'HD') pointer = blocks['HD_comment']['block_start'] + blocks['HD_comment']['block_length'] # file history block @@ -1560,7 +1560,7 @@ def write4(self, file_name=None, compression=False): blocks['FH']['MD'] = pointer blocks['FH_comment'] = CommentBlock() blocks['FH_comment']['block_start'] = pointer - blocks['FH_comment'].load(self.file_metadata, 'FH') + blocks['FH_comment'].load(self.fileMetadata, 'FH') pointer = blocks['FH_comment']['block_start'] + blocks['FH_comment']['block_length'] # write DG block diff --git a/mdfreader/mdfreader.py b/mdfreader/mdfreader.py index 53b783f..c8ae1a3 100644 --- a/mdfreader/mdfreader.py +++ b/mdfreader/mdfreader.py @@ -869,13 +869,13 @@ def set_attribute(f, name, value): file_name = splitext(self.fileName)[0] file_name = file_name + '.nc' f = netcdf.netcdf_file(file_name, 'w') - set_attribute(f, 'Date', self.file_metadata['date']) - set_attribute(f, 'Time', self.file_metadata['time']) - set_attribute(f, 'Author', self.file_metadata['author']) - set_attribute(f, 'Organization', self.file_metadata['organisation']) - set_attribute(f, 'ProjectName', self.file_metadata['project']) - set_attribute(f, 'Subject', self.file_metadata['subject']) - set_attribute(f, 'Comment', self.file_metadata['comment']) + set_attribute(f, 'Date', self.fileMetadata['date']) + set_attribute(f, 'Time', self.fileMetadata['time']) + set_attribute(f, 'Author', self.fileMetadata['author']) + set_attribute(f, 'Organization', self.fileMetadata['organisation']) + set_attribute(f, 'ProjectName', self.fileMetadata['project']) + set_attribute(f, 'Subject', self.fileMetadata['subject']) + set_attribute(f, 'Comment', self.fileMetadata['comment']) # Create dimensions having name of all time channels for master in list(self.masterChannelList.keys()): f.createDimension(master, len(self.get_channel_data(self.masterChannelList[master][0]))) @@ -980,14 +980,14 @@ def set_attribute(obj, name, value): f = h5py.File(file_name, 'w') # create hdf5 file # create group in root associated to file file_group = f.create_group(os.path.basename(file_name)) - set_attribute(file_group, 'Author', self.file_metadata['author']) - set_attribute(file_group, 'Date', self.file_metadata['date']) - set_attribute(file_group, 'Time', self.file_metadata['time']) - set_attribute(file_group, 'Time', self.file_metadata['time']) - set_attribute(file_group, 'Organization', self.file_metadata['organisation']) - set_attribute(file_group, 'ProjectName', self.file_metadata['project']) - set_attribute(file_group, 'Subject', self.file_metadata['subject']) - set_attribute(file_group, 'Comment', self.file_metadata['comment']) + set_attribute(file_group, 'Author', self.fileMetadata['author']) + set_attribute(file_group, 'Date', self.fileMetadata['date']) + set_attribute(file_group, 'Time', self.fileMetadata['time']) + set_attribute(file_group, 'Time', self.fileMetadata['time']) + set_attribute(file_group, 'Organization', self.fileMetadata['organisation']) + set_attribute(file_group, 'ProjectName', self.fileMetadata['project']) + set_attribute(file_group, 'Subject', self.fileMetadata['subject']) + set_attribute(file_group, 'Comment', self.fileMetadata['comment']) master_type_dict = {0: 'None', 1: 'Time', 2: 'Angle', 3: 'Distance', 4: 'Index', None: 'None'} if len(list(self.masterChannelList.keys())) > 1: # if several time groups of channels, not resampled @@ -1282,9 +1282,9 @@ def convert_to_pandas(self, sampling=None): warn('Module pandas missing') if sampling is not None: self.resample(sampling) - if self.file_metadata['date'] != '' and self.file_metadata['time'] != '': - date = self.file_metadata['date'].replace(':', '-') - time = self.file_metadata['time'] + if self.fileMetadata['date'] != '' and self.fileMetadata['time'] != '': + date = self.fileMetadata['date'].replace(':', '-') + time = self.fileMetadata['time'] datetime_info = datetime64(date + 'T' + time) else: datetime_info = datetime64(datetime.now()) From 4fb9b1ed42e590a28f8feae7a3274bad8fbe5918 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Thu, 1 Nov 2018 10:00:32 +0100 Subject: [PATCH 44/61] bit_masking_needed used as both method and attribute in Channel4 --- mdfreader/channel.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mdfreader/channel.py b/mdfreader/channel.py index cea4e85..91ec19c 100644 --- a/mdfreader/channel.py +++ b/mdfreader/channel.py @@ -154,6 +154,7 @@ def __init__(self): self.VLSD_CG_Flag = False self.nBytes = 0 self.byteOffset = 0 + #self.bit_masking_needed = True def __str__(self): """ channel object attributes print @@ -890,7 +891,7 @@ def change_channel_name(self, channel_group): """ self.name = '{0}_{1}'.format(self.name, channel_group) - def bit_masking_needed(self, info): + def bit_masking_need(self, info): """ Valid if bit masking need Parameters From 778e9df83a074c55d2c004eab3a6b7147b7bc351 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Thu, 1 Nov 2018 13:12:13 +0100 Subject: [PATCH 45/61] fixed bug with bit_masking_needed, wrong indexing --- mdfreader/mdf3reader.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mdfreader/mdf3reader.py b/mdfreader/mdf3reader.py index 918f221..1b740e4 100644 --- a/mdfreader/mdf3reader.py +++ b/mdfreader/mdf3reader.py @@ -537,7 +537,8 @@ def read_sorted_record(self, fid, pointer, channel_set=None): chan.bitOffset, chan.posByteBeg, chan.nBytes, 0) - self[id].bit_masking_needed = False # masking already considered in dataRead + # masking already considered in dataRead + self[rec_chan[id].channelNumber].bit_masking_needed = False previous_index += n_record_chunk return rec except: From ca07c168b5b2af2674184c0a8ddd28af0648ff9c Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Thu, 1 Nov 2018 15:17:59 +0100 Subject: [PATCH 46/61] Some pep8 refactoring for dataRead --- dataRead.pyx | 790 ++++++++++++++++++++-------------------- mdfreader/mdf3reader.py | 20 +- mdfreader/mdf4reader.py | 14 +- 3 files changed, 412 insertions(+), 412 deletions(-) diff --git a/dataRead.pyx b/dataRead.pyx index a12e0e0..2daa003 100644 --- a/dataRead.pyx +++ b/dataRead.pyx @@ -5,221 +5,221 @@ from sys import byteorder from cpython.bytes cimport PyBytes_AsString from libc.string cimport memcpy - + #@cython.boundscheck(False) #@cython.wraparound(False) -def dataRead(bytes tmp, unsigned short bitCount, - unsigned short signalDataType, str RecordFormat, unsigned long long numberOfRecords, - unsigned long record_byte_size, unsigned char bitOffset, - unsigned long posByteBeg, unsigned long nBytes, array): +def data_read(bytes tmp, unsigned short bit_count, + unsigned short signal_data_type, str record_format, unsigned long long number_of_records, + unsigned long record_byte_size, unsigned char bit_offset, + unsigned long pos_byte_beg, unsigned long n_bytes, array): """dataRead function to read in cython a channel from a byte stream Parameters ------------ tmp : bytes byte stream - bitCount : unsigned short + bit_count : unsigned short number of bit taken by the channel in the record - signalDataType : unsigned short + signal_data_type : unsigned short int to describe data type - RecordFormat : string + record_format : string basic numpy dtype description of data type, used to create - returned numpy ndarray - numberOfRecords : unsigned long long + returned numpy ndarray + number_of_records : unsigned long long number of records in byte stream record_byte_size : unsigned long number of bytes taken by one record repeated in byte stream - bitOffset : unsigned char + bit_offset : unsigned char bit offset of data in C aligned bytes - posByteBeg : unsigned long + pos_byte_beg : unsigned long beginning byte position of channel in record - nBytes : unsigned long + n_bytes : unsigned long bytes length of channel in record array : boolean reads an array, not a vector Returns ------- - ndarray of type RecordFormat with numberOfRecords records. + ndarray of type record_format with number_of_records records. Byte order is swapped if necessary to match machine byte order before bits offset and masking """ - cdef char* bita = PyBytes_AsString(tmp) + cdef char* bit_stream = PyBytes_AsString(tmp) if not array: - if 'V' in RecordFormat or 'S' in RecordFormat or RecordFormat is None: - return dataReadByte(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) - elif signalDataType in (4, 5) and nBytes == 4: # float - if (byteorder == 'little' and signalDataType == 4) or \ - (byteorder == 'big' and signalDataType == 5): - return dataReadFloat(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, 0) + if 'V' in record_format or 'S' in record_format or record_format is None: + return read_byte(bit_stream, record_format, number_of_records, + record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset) + elif signal_data_type in (4, 5) and n_bytes == 4: # float + if (byteorder == 'little' and signal_data_type == 4) or \ + (byteorder == 'big' and signal_data_type == 5): + return read_float(bit_stream, record_format, number_of_records, + record_byte_size, pos_byte_beg, 0) else: # swap bytes - return dataReadFloat(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, 1) - elif signalDataType in (4, 5) and nBytes == 8: # double - if (byteorder == 'little' and signalDataType == 4) or \ - (byteorder == 'big' and signalDataType == 5): - return dataReadDouble(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, 0) + return read_float(bit_stream, record_format, number_of_records, + record_byte_size, pos_byte_beg, 1) + elif signal_data_type in (4, 5) and n_bytes == 8: # double + if (byteorder == 'little' and signal_data_type == 4) or \ + (byteorder == 'big' and signal_data_type == 5): + return read_double(bit_stream, record_format, number_of_records, + record_byte_size, pos_byte_beg, 0) else: # swap bytes - return dataReadDouble(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, 1) - elif signalDataType in (0, 1, 13) and nBytes == 1: # unsigned char - return dataReadUChar(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, bitCount, bitOffset) - elif signalDataType in (2, 3) and nBytes == 1: # signed char - return dataReadChar(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, bitCount, bitOffset) - elif signalDataType in (0, 1, 13, 14) and nBytes <= 2: # unsigned short - if (byteorder == 'little' and signalDataType == 0) or \ - (byteorder == 'big' and signalDataType == 1): - return dataReadUShort(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, bitCount, bitOffset, 0) + return read_double(bit_stream, record_format, number_of_records, + record_byte_size, pos_byte_beg, 1) + elif signal_data_type in (0, 1, 13) and n_bytes == 1: # unsigned char + return read_unsigned_char(bit_stream, record_format, number_of_records, + record_byte_size, pos_byte_beg, bit_count, bit_offset) + elif signal_data_type in (2, 3) and n_bytes == 1: # signed char + return read_signed_char(bit_stream, record_format, number_of_records, + record_byte_size, pos_byte_beg, bit_count, bit_offset) + elif signal_data_type in (0, 1, 13, 14) and n_bytes <= 2: # unsigned short + if (byteorder == 'little' and signal_data_type == 0) or \ + (byteorder == 'big' and signal_data_type == 1): + return read_unsigned_short(bit_stream, record_format, number_of_records, + record_byte_size, pos_byte_beg, bit_count, bit_offset, 0) else: # swap bytes - return dataReadUShort(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, bitCount, bitOffset, 1) - elif signalDataType in (2, 3) and nBytes <= 2: # signed short - if (byteorder == 'little' and signalDataType == 2) or \ - (byteorder == 'big' and signalDataType == 3): - return dataReadShort(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, bitCount, bitOffset, 0) + return read_unsigned_short(bit_stream, record_format, number_of_records, + record_byte_size, pos_byte_beg, bit_count, bit_offset, 1) + elif signal_data_type in (2, 3) and n_bytes <= 2: # signed short + if (byteorder == 'little' and signal_data_type == 2) or \ + (byteorder == 'big' and signal_data_type == 3): + return read_signed_short(bit_stream, record_format, number_of_records, + record_byte_size, pos_byte_beg, bit_count, bit_offset, 0) else: # swap bytes - return dataReadShort(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, bitCount, bitOffset, 1) - elif signalDataType in (0, 1, 14) and nBytes <= 4: # unsigned int - if (byteorder == 'little' and signalDataType == 0) or \ - (byteorder == 'big' and signalDataType == 1): - return dataReadUInt(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) + return read_signed_short(bit_stream, record_format, number_of_records, + record_byte_size, pos_byte_beg, bit_count, bit_offset, 1) + elif signal_data_type in (0, 1, 14) and n_bytes <= 4: # unsigned int + if (byteorder == 'little' and signal_data_type == 0) or \ + (byteorder == 'big' and signal_data_type == 1): + return read_unsigned_int(bit_stream, record_format, number_of_records, + record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 0) else: # swap bytes - return dataReadUInt(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - elif signalDataType in (2, 3) and nBytes <= 4: # signed int - if (byteorder == 'little' and signalDataType == 2) or \ - (byteorder == 'big' and signalDataType == 3): - return dataReadInt(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) + return read_unsigned_int(bit_stream, record_format, number_of_records, + record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) + elif signal_data_type in (2, 3) and n_bytes <= 4: # signed int + if (byteorder == 'little' and signal_data_type == 2) or \ + (byteorder == 'big' and signal_data_type == 3): + return read_signed_int(bit_stream, record_format, number_of_records, + record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 0) else: # swap bytes - return dataReadInt(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - elif signalDataType in (0, 1) and nBytes <= 8: # unsigned long long - if (byteorder == 'little' and signalDataType == 0) or \ - (byteorder == 'big' and signalDataType == 1): - return dataReadULongLong(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) + return read_signed_int(bit_stream, record_format, number_of_records, + record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) + elif signal_data_type in (0, 1) and n_bytes <= 8: # unsigned long long + if (byteorder == 'little' and signal_data_type == 0) or \ + (byteorder == 'big' and signal_data_type == 1): + return read_unsigned_longlong(bit_stream, record_format, number_of_records, + record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 0) else: # swap bytes - return dataReadULongLong(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - elif signalDataType in (2, 3) and nBytes <= 8: # signed long long - if (byteorder == 'little' and signalDataType == 0) or \ - (byteorder == 'big' and signalDataType == 1): - return dataReadLongLong(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) + return read_unsigned_longlong(bit_stream, record_format, number_of_records, + record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) + elif signal_data_type in (2, 3) and n_bytes <= 8: # signed long long + if (byteorder == 'little' and signal_data_type == 0) or \ + (byteorder == 'big' and signal_data_type == 1): + return read_signed_longlong(bit_stream, record_format, number_of_records, + record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 0) else: # swap bytes - return dataReadLongLong(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) + return read_signed_longlong(bit_stream, record_format, number_of_records, + record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) else: - return dataReadByte(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) + return read_byte(bit_stream, record_format, number_of_records, + record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset) else: # array - if (byteorder == 'little' and signalDataType in (0, 2, 4)) or \ - (byteorder == 'big' and signalDataType in (1, 3, 5)): - return dataReadArray(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, nBytes, bitCount, bitOffset, 0) + if (byteorder == 'little' and signal_data_type in (0, 2, 4)) or \ + (byteorder == 'big' and signal_data_type in (1, 3, 5)): + return read_array(bit_stream, record_format, number_of_records, + record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset, 0) else: # swap bytes - return dataReadArray(bita, RecordFormat, numberOfRecords, - record_byte_size, posByteBeg, nBytes, bitCount, bitOffset, 1) + return read_array(bit_stream, record_format, number_of_records, + record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset, 1) -cdef inline dataReadFloat(const char* bita, str RecordFormat, unsigned long long numberOfRecords, - unsigned long record_byte_size, unsigned long posByteBeg, unsigned char swap): - cdef np.ndarray[np.float32_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array +cdef inline read_float(const char* bit_stream, str record_format, unsigned long long number_of_records, + unsigned long record_byte_size, unsigned long pos_byte_beg, unsigned char swap): + cdef np.ndarray[np.float32_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array cdef unsigned long long i - cdef float tempfloat = 0 + cdef float temp_float = 0 cdef char temp[4] - for i in range(numberOfRecords): - memcpy(&tempfloat, &bita[posByteBeg + record_byte_size * i], 4) - buf[i] = tempfloat + for i in range(number_of_records): + memcpy(&temp_float, &bit_stream[pos_byte_beg + record_byte_size * i], 4) + buf[i] = temp_float if swap == 0: return buf else: return buf.byteswap() -cdef inline dataReadDouble(const char* bita, str RecordFormat, unsigned long long numberOfRecords, - unsigned long record_byte_size, unsigned long posByteBeg, unsigned char swap): - cdef np.ndarray[np.float64_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array +cdef inline read_double(const char* bit_stream, str record_format, unsigned long long number_of_records, + unsigned long record_byte_size, unsigned long pos_byte_beg, unsigned char swap): + cdef np.ndarray[np.float64_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array cdef unsigned long long i - cdef double tempDouble = 0 + cdef double temp_double = 0 cdef char temp[8] - for i in range(numberOfRecords): - memcpy(&tempDouble, &bita[posByteBeg + record_byte_size * i], 8) - buf[i] = tempDouble + for i in range(number_of_records): + memcpy(&temp_double, &bit_stream[pos_byte_beg + record_byte_size * i], 8) + buf[i] = temp_double if swap == 0: return buf else: return buf.byteswap() -cdef inline dataReadUChar(const char* bita, str RecordFormat, unsigned long long numberOfRecords, - unsigned long record_byte_size, unsigned long posByteBeg, - unsigned long bitCount, unsigned char bitOffset): - cdef np.ndarray[np.uint8_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array +cdef inline read_unsigned_char(const char* bit_stream, str record_format, unsigned long long number_of_records, + unsigned long record_byte_size, unsigned long pos_byte_beg, + unsigned long bit_count, unsigned char bit_offset): + cdef np.ndarray[np.uint8_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array cdef unsigned long long i - cdef unsigned char mask = ((1 << bitCount) - 1) + cdef unsigned char mask = ((1 << bit_count) - 1) cdef unsigned char temp1byte = 0 - if bitCount == 8: - for i in range(numberOfRecords): - memcpy(&temp1byte, &bita[posByteBeg + record_byte_size * i], 1) + if bit_count == 8: + for i in range(number_of_records): + memcpy(&temp1byte, &bit_stream[pos_byte_beg + record_byte_size * i], 1) buf[i] = temp1byte else: - for i in range(numberOfRecords): - memcpy(&temp1byte, &bita[posByteBeg + record_byte_size * i], 1) + for i in range(number_of_records): + memcpy(&temp1byte, &bit_stream[pos_byte_beg + record_byte_size * i], 1) # right shift - if bitOffset > 0: - temp1byte = temp1byte >> bitOffset + if bit_offset > 0: + temp1byte = temp1byte >> bit_offset # mask left part temp1byte &= mask buf[i] = temp1byte return buf -cdef inline dataReadChar(const char* bita, str RecordFormat, unsigned long long numberOfRecords, - unsigned long record_byte_size, unsigned long posByteBeg, - unsigned long bitCount, unsigned char bitOffset): - cdef np.ndarray[np.int8_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array +cdef inline read_signed_char(const char* bit_stream, str record_format, unsigned long long number_of_records, + unsigned long record_byte_size, unsigned long pos_byte_beg, + unsigned long bit_count, unsigned char bit_offset): + cdef np.ndarray[np.int8_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array cdef unsigned long long i - cdef char mask = ((1 << bitCount) - 1) + cdef char mask = ((1 << bit_count) - 1) cdef char temp1byte = 0 - cdef char signBit = 0 - cdef char signBitMask = (1 << (bitCount-1)) - cdef char signExtend = ((1 << (8 - bitCount)) - 1) << bitCount - if bitCount == 8: - for i in range(numberOfRecords): - memcpy(&temp1byte, &bita[posByteBeg + record_byte_size * i], 1) + cdef char sign_bit = 0 + cdef char sign_bit_mask = (1 << (bit_count-1)) + cdef char sign_extend = ((1 << (8 - bit_count)) - 1) << bit_count + if bit_count == 8: + for i in range(number_of_records): + memcpy(&temp1byte, &bit_stream[pos_byte_beg + record_byte_size * i], 1) buf[i] = temp1byte else: - for i in range(numberOfRecords): - memcpy(&temp1byte, &bita[posByteBeg + record_byte_size * i], 1) + for i in range(number_of_records): + memcpy(&temp1byte, &bit_stream[pos_byte_beg + record_byte_size * i], 1) # right shift - if bitOffset > 0: - temp1byte = temp1byte >> bitOffset + if bit_offset > 0: + temp1byte = temp1byte >> bit_offset # mask left part temp1byte &= mask - signBit = temp1byte & signBitMask - if signBit: # negative value, sign extend - temp1byte |= signExtend + sign_bit = temp1byte & sign_bit_mask + if sign_bit: # negative value, sign extend + temp1byte |= sign_extend buf[i] = temp1byte return buf -cdef inline dataReadUShort(const char* bita, str RecordFormat, unsigned long long numberOfRecords, - unsigned long record_byte_size, unsigned long posByteBeg, - unsigned long bitCount, unsigned char bitOffset, unsigned char swap): - cdef np.ndarray[np.uint16_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array +cdef inline read_unsigned_short(const char* bit_stream, str record_format, unsigned long long number_of_records, + unsigned long record_byte_size, unsigned long pos_byte_beg, + unsigned long bit_count, unsigned char bit_offset, unsigned char swap): + cdef np.ndarray[np.uint16_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array cdef unsigned long long i - cdef unsigned short mask = ((1 << bitCount) - 1) + cdef unsigned short mask = ((1 << bit_count) - 1) cdef unsigned short temp2byte = 0 cdef char temp[2] - if bitCount == 16: - for i in range(numberOfRecords): - memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + if bit_count == 16: + for i in range(number_of_records): + memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) buf[i] = temp2byte if swap == 0: return buf @@ -227,42 +227,42 @@ cdef inline dataReadUShort(const char* bita, str RecordFormat, unsigned long lon return buf.byteswap() else: if swap == 0: - for i in range(numberOfRecords): - memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + for i in range(number_of_records): + memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) # right shift - if bitOffset > 0: - temp2byte = temp2byte >> bitOffset + if bit_offset > 0: + temp2byte = temp2byte >> bit_offset # mask left part - if bitCount < 16: + if bit_count < 16: temp2byte &= mask buf[i] = temp2byte else: - for i in range(numberOfRecords): - memcpy(&temp, &bita[posByteBeg + record_byte_size * i], 2) + for i in range(number_of_records): + memcpy(&temp, &bit_stream[pos_byte_beg + record_byte_size * i], 2) temp2byte = temp[0]<<8 | temp[1] # swap bytes # right shift - if bitOffset > 0: - temp2byte = temp2byte >> bitOffset + if bit_offset > 0: + temp2byte = temp2byte >> bit_offset # mask left part - if bitCount < 16: + if bit_count < 16: temp2byte &= mask buf[i] = temp2byte return buf -cdef inline dataReadShort(const char* bita, str RecordFormat, unsigned long long numberOfRecords, - unsigned long record_byte_size, unsigned long posByteBeg, - unsigned long bitCount, unsigned char bitOffset, unsigned char swap): - cdef np.ndarray[np.int16_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array +cdef inline read_signed_short(const char* bit_stream, str record_format, unsigned long long number_of_records, + unsigned long record_byte_size, unsigned long pos_byte_beg, + unsigned long bit_count, unsigned char bit_offset, unsigned char swap): + cdef np.ndarray[np.int16_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array cdef unsigned long long i - cdef short mask = ((1 << bitCount) - 1) + cdef short mask = ((1 << bit_count) - 1) cdef short temp2byte = 0 - cdef short signBit = 0 - cdef short signBitMask = (1 << (bitCount-1)) - cdef short signExtend = ((1 << (16 - bitCount)) - 1) << bitCount + cdef short sign_bit = 0 + cdef short sign_bit_mask = (1 << (bit_count-1)) + cdef short sign_extend = ((1 << (16 - bit_count)) - 1) << bit_count cdef char temp[2] - if bitCount == 16: - for i in range(numberOfRecords): - memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + if bit_count == 16: + for i in range(number_of_records): + memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) buf[i] = temp2byte if swap == 0: return buf @@ -270,449 +270,449 @@ cdef inline dataReadShort(const char* bita, str RecordFormat, unsigned long long return buf.byteswap() else: if swap == 0: - for i in range(numberOfRecords): - memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + for i in range(number_of_records): + memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) # right shift - if bitOffset > 0: - temp2byte = temp2byte >> bitOffset + if bit_offset > 0: + temp2byte = temp2byte >> bit_offset # mask left part temp2byte &= mask - signBit = temp2byte & signBitMask - if signBit: # negative value, sign extend - temp2byte |= signExtend + sign_bit = temp2byte & sign_bit_mask + if sign_bit: # negative value, sign extend + temp2byte |= sign_extend buf[i] = temp2byte else: - for i in range(numberOfRecords): - memcpy(&temp, &bita[posByteBeg + record_byte_size * i], 2) + for i in range(number_of_records): + memcpy(&temp, &bit_stream[pos_byte_beg + record_byte_size * i], 2) temp2byte = temp[0]<<8 | temp[1] # swap bytes # right shift - if bitOffset > 0: - temp2byte = temp2byte >> bitOffset + if bit_offset > 0: + temp2byte = temp2byte >> bit_offset # mask left part temp2byte &= mask - signBit = temp2byte & signBitMask - if signBit: # negative value, sign extend - temp2byte |= signExtend + sign_bit = temp2byte & sign_bit_mask + if sign_bit: # negative value, sign extend + temp2byte |= sign_extend buf[i] = temp2byte return buf -cdef inline dataReadUInt(const char* bita, str RecordFormat, unsigned long long numberOfRecords, - unsigned long record_byte_size, unsigned long posByteBeg, - unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): - cdef np.ndarray[np.uint32_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array +cdef inline read_unsigned_int(const char* bit_stream, str record_format, unsigned long long number_of_records, + unsigned long record_byte_size, unsigned long pos_byte_beg, + unsigned long bit_count, unsigned char bit_offset, unsigned long n_bytes, unsigned char swap): + cdef np.ndarray[np.uint32_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array cdef unsigned long long i - cdef unsigned int mask = ((1 << bitCount) - 1) + cdef unsigned int mask = ((1 << bit_count) - 1) cdef unsigned int temp4byte = 0 cdef char temp4[4] cdef char temp3[3] - if bitCount == 32: - for i in range(numberOfRecords): - memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) + if bit_count == 32: + for i in range(number_of_records): + memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], 4) buf[i] = temp4byte if swap == 0: return buf else: return buf.byteswap() - elif nBytes == 4: + elif n_bytes == 4: if swap == 0: - for i in range(numberOfRecords): - memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # right shift - if bitOffset > 0: - temp4byte = temp4byte >> bitOffset + if bit_offset > 0: + temp4byte = temp4byte >> bit_offset # mask left part - if bitCount < 32: + if bit_count < 32: temp4byte &= mask buf[i] = temp4byte else: - for i in range(numberOfRecords): - memcpy(&temp4, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp4, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) temp4byte = temp4[0]<<24 | temp4[1]<<16 | temp4[2]<<8 | temp4[3] # swap bytes # right shift - if bitOffset > 0: - temp4byte = temp4byte >> bitOffset + if bit_offset > 0: + temp4byte = temp4byte >> bit_offset # mask left part - if bitCount < 32: + if bit_count < 32: temp4byte &= mask buf[i] = temp4byte return buf else: # on 3 bytes if swap == 0: - for i in range(numberOfRecords): - memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # right shift - if bitOffset > 0: - temp4byte = temp4byte >> bitOffset + if bit_offset > 0: + temp4byte = temp4byte >> bit_offset # mask left part - if bitCount < 24: + if bit_count < 24: temp4byte &= mask buf[i] = temp4byte else: - for i in range(numberOfRecords): - memcpy(&temp3, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp3, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) temp4byte = temp3[0]<<16 | temp3[1]<<8 | temp3[2] # swap bytes # right shift - if bitOffset > 0: - temp4byte = temp4byte >> bitOffset + if bit_offset > 0: + temp4byte = temp4byte >> bit_offset # mask left part - if bitCount < 24: + if bit_count < 24: temp4byte &= mask buf[i] = temp4byte return buf -cdef inline dataReadInt(const char* bita, str RecordFormat, unsigned long long numberOfRecords, - unsigned long record_byte_size, unsigned long posByteBeg, - unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): - cdef np.ndarray[np.int32_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array +cdef inline read_signed_int(const char* bit_stream, str record_format, unsigned long long number_of_records, + unsigned long record_byte_size, unsigned long pos_byte_beg, + unsigned long bit_count, unsigned char bit_offset, unsigned long n_bytes, unsigned char swap): + cdef np.ndarray[np.int32_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array cdef unsigned long long i - cdef int mask = ((1 << bitCount) - 1) + cdef int mask = ((1 << bit_count) - 1) cdef int temp4byte = 0 - cdef int signBit = 0 - cdef int signBitMask = (1 << (bitCount-1)) - cdef int signExtend = ((1 << (32 - bitCount)) - 1) << bitCount + cdef int sign_bit = 0 + cdef int sign_bit_mask = (1 << (bit_count-1)) + cdef int sign_extend = ((1 << (32 - bit_count)) - 1) << bit_count cdef char temp4[4] cdef char temp3[3] - if bitCount == 32: - for i in range(numberOfRecords): - memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) + if bit_count == 32: + for i in range(number_of_records): + memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], 4) buf[i] = temp4byte if swap == 0: return buf else: return buf.byteswap() - elif nBytes == 4: + elif n_bytes == 4: if swap == 0: - for i in range(numberOfRecords): - memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # right shift - if bitOffset > 0: - temp4byte = temp4byte >> bitOffset + if bit_offset > 0: + temp4byte = temp4byte >> bit_offset # mask left part - if bitCount < 32: + if bit_count < 32: temp4byte &= mask - signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed - if signBit: # negative value, sign extend - temp4byte |= signExtend + sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed + if sign_bit: # negative value, sign extend + temp4byte |= sign_extend buf[i] = temp4byte else: - for i in range(numberOfRecords): - memcpy(&temp4, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp4, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) temp4byte = temp4[0]<<24 | temp4[1]<<16 | temp4[2]<<8 | temp4[3] # swap bytes # right shift - if bitOffset > 0: - temp4byte = temp4byte >> bitOffset + if bit_offset > 0: + temp4byte = temp4byte >> bit_offset # mask left part - if bitCount < 32: + if bit_count < 32: temp4byte &= mask - signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed - if signBit: # negative value, sign extend - temp4byte |= signExtend + sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed + if sign_bit: # negative value, sign extend + temp4byte |= sign_extend buf[i] = temp4byte return buf else: # on 3 bytes if swap == 0: - for i in range(numberOfRecords): - memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # right shift - if bitOffset > 0: - temp4byte = temp4byte >> bitOffset + if bit_offset > 0: + temp4byte = temp4byte >> bit_offset # mask left part - if bitCount < 24: + if bit_count < 24: temp4byte &= mask - signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed - if signBit: # negative value, sign extend - temp4byte |= signExtend + sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed + if sign_bit: # negative value, sign extend + temp4byte |= sign_extend buf[i] = temp4byte else: - for i in range(numberOfRecords): - memcpy(&temp3, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp3, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) temp4byte = temp3[0]<<16 | temp3[1]<<8 | temp3[2] # swap bytes # right shift - if bitOffset > 0: - temp4byte = temp4byte >> bitOffset + if bit_offset > 0: + temp4byte = temp4byte >> bit_offset # mask left part - if bitCount < 24: + if bit_count < 24: temp4byte &= mask - signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed - if signBit: # negative value, sign extend - temp4byte |= signExtend + sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed + if sign_bit: # negative value, sign extend + temp4byte |= sign_extend buf[i] = temp4byte return buf -cdef inline dataReadULongLong(const char* bita, str RecordFormat, unsigned long long numberOfRecords, - unsigned long record_byte_size, unsigned long posByteBeg, - unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): - cdef np.ndarray[np.uint64_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array +cdef inline read_unsigned_longlong(const char* bit_stream, str record_format, unsigned long long number_of_records, + unsigned long record_byte_size, unsigned long pos_byte_beg, + unsigned long bit_count, unsigned char bit_offset, unsigned long n_bytes, unsigned char swap): + cdef np.ndarray[np.uint64_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array cdef unsigned long long i - cdef unsigned long long mask = ((1 << bitCount) - 1) + cdef unsigned long long mask = ((1 << bit_count) - 1) cdef unsigned long long temp8byte = 0 cdef char temp8[8] cdef char temp7[7] cdef char temp6[6] cdef char temp5[5] - if bitCount == 64: - for i in range(numberOfRecords): - memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + if bit_count == 64: + for i in range(number_of_records): + memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) buf[i] = temp8byte if swap == 0: return buf else: return buf.byteswap() - elif nBytes == 8: + elif n_bytes == 8: if swap == 0: - for i in range(numberOfRecords): - memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # right shift - if bitOffset > 0: - temp8byte = temp8byte >> bitOffset + if bit_offset > 0: + temp8byte = temp8byte >> bit_offset # mask left part - if bitCount < 64: + if bit_count < 64: temp8byte &= mask buf[i] = temp8byte else: - for i in range(numberOfRecords): - memcpy(&temp8, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp8, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) temp8byte = temp8[0]<<56 | temp8[1]<<48 | temp8[2]<<40 | temp8[3]<<32 | \ temp8[4]<<24 | temp8[5]<<16 | temp8[6]<<8 | temp8[7] # swap bytes # right shift - if bitOffset > 0: - temp8byte = temp8byte >> bitOffset + if bit_offset > 0: + temp8byte = temp8byte >> bit_offset # mask left part - if bitCount < 64: + if bit_count < 64: temp8byte &= mask buf[i] = temp8byte - elif nBytes == 7: + elif n_bytes == 7: if swap == 0: - for i in range(numberOfRecords): - memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # right shift - if bitOffset > 0: - temp8byte = temp8byte >> bitOffset + if bit_offset > 0: + temp8byte = temp8byte >> bit_offset # mask left part - if bitCount < 56: + if bit_count < 56: temp8byte &= mask buf[i] = temp8byte else: - for i in range(numberOfRecords): - memcpy(&temp7, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp7, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) temp8byte = temp7[0]<<48 | temp7[1]<<40 | temp7[2]<<32 | \ temp7[3]<<24 | temp7[4]<<16 | temp7[5]<<8 | temp7[6] # swap bytes # right shift - if bitOffset > 0: - temp8byte = temp8byte >> bitOffset + if bit_offset > 0: + temp8byte = temp8byte >> bit_offset # mask left part - if bitCount < 56: + if bit_count < 56: temp8byte &= mask buf[i] = temp8byte - elif nBytes == 6: + elif n_bytes == 6: if swap == 0: - for i in range(numberOfRecords): - memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # right shift - if bitOffset > 0: - temp8byte = temp8byte >> bitOffset + if bit_offset > 0: + temp8byte = temp8byte >> bit_offset # mask left part - if bitCount < 48: + if bit_count < 48: temp8byte &= mask buf[i] = temp8byte else: - for i in range(numberOfRecords): - memcpy(&temp6, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp6, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) temp8byte = temp6[0]<<40 | temp6[1]<<32 | temp6[2]<<24 | \ temp6[3]<<16 | temp6[4]<<8 | temp6[5] # swap bytes # right shift - if bitOffset > 0: - temp8byte = temp8byte >> bitOffset + if bit_offset > 0: + temp8byte = temp8byte >> bit_offset # mask left part - if bitCount < 48: + if bit_count < 48: temp8byte &= mask buf[i] = temp8byte - elif nBytes == 5: + elif n_bytes == 5: if swap == 0: - for i in range(numberOfRecords): - memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # right shift - if bitOffset > 0: - temp8byte = temp8byte >> bitOffset + if bit_offset > 0: + temp8byte = temp8byte >> bit_offset # mask left part - if bitCount < 32: + if bit_count < 32: temp8byte &= mask buf[i] = temp8byte else: - for i in range(numberOfRecords): - memcpy(&temp5, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp5, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) temp8byte = temp5[0]<<32 | temp5[1]<<24 | \ temp5[2]<<16 | temp5[3]<<8 | temp5[4] # swap bytes # right shift - if bitOffset > 0: - temp8byte = temp8byte >> bitOffset + if bit_offset > 0: + temp8byte = temp8byte >> bit_offset # mask left part - if bitCount < 32: + if bit_count < 32: temp8byte &= mask buf[i] = temp8byte return buf -cdef inline dataReadLongLong(const char* bita, str RecordFormat, unsigned long long numberOfRecords, - unsigned long record_byte_size, unsigned long posByteBeg, - unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): - cdef np.ndarray[np.int64_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array +cdef inline read_signed_longlong(const char* bit_stream, str record_format, unsigned long long number_of_records, + unsigned long record_byte_size, unsigned long pos_byte_beg, + unsigned long bit_count, unsigned char bit_offset, unsigned long n_bytes, unsigned char swap): + cdef np.ndarray[np.int64_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array cdef unsigned long long i - cdef long long mask = ((1 << bitCount) - 1) + cdef long long mask = ((1 << bit_count) - 1) cdef long long temp8byte = 0 - cdef long signBit = 0 - cdef long long signBitMask = (1 << (bitCount-1)) - cdef long long signExtend = ((1 << (64 - bitCount)) - 1) << bitCount + cdef long sign_bit = 0 + cdef long long sign_bit_mask = (1 << (bit_count-1)) + cdef long long sign_extend = ((1 << (64 - bit_count)) - 1) << bit_count cdef char temp8[8] cdef char temp7[7] cdef char temp6[6] cdef char temp5[5] - if bitCount == 64: - for i in range(numberOfRecords): - memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + if bit_count == 64: + for i in range(number_of_records): + memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) buf[i] = temp8byte if swap == 0: return buf else: return buf.byteswap() - elif nBytes == 8: + elif n_bytes == 8: if swap == 0: - for i in range(numberOfRecords): - memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # right shift - if bitOffset > 0: - temp8byte = temp8byte >> bitOffset + if bit_offset > 0: + temp8byte = temp8byte >> bit_offset # mask left part - if bitCount < 64: + if bit_count < 64: temp8byte &= mask - signBit = temp8byte & signBitMask - if signBit: # negative value, sign extend - temp8byte |= signExtend + sign_bit = temp8byte & sign_bit_mask + if sign_bit: # negative value, sign extend + temp8byte |= sign_extend buf[i] = temp8byte else: - for i in range(numberOfRecords): - memcpy(&temp8, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp8, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) temp8byte = temp8[0]<<56 | temp8[1]<<48 | temp8[2]<<40 | temp8[3]<<32 | \ temp8[4]<<24 | temp8[5]<<16 | temp8[6]<<8 | temp8[7] # swap bytes # right shift - if bitOffset > 0: - temp8byte = temp8byte >> bitOffset + if bit_offset > 0: + temp8byte = temp8byte >> bit_offset # mask left part - if bitCount < 64: + if bit_count < 64: temp8byte &= mask - signBit = temp8byte & signBitMask - if signBit: # negative value, sign extend - temp8byte |= signExtend + sign_bit = temp8byte & sign_bit_mask + if sign_bit: # negative value, sign extend + temp8byte |= sign_extend buf[i] = temp8byte - elif nBytes == 7: + elif n_bytes == 7: if swap == 0: - for i in range(numberOfRecords): - memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # right shift - if bitOffset > 0: - temp8byte = temp8byte >> bitOffset + if bit_offset > 0: + temp8byte = temp8byte >> bit_offset # mask left part - if bitCount < 56: + if bit_count < 56: temp8byte &= mask - signBit = temp8byte & signBitMask - if signBit: # negative value, sign extend - temp8byte |= signExtend + sign_bit = temp8byte & sign_bit_mask + if sign_bit: # negative value, sign extend + temp8byte |= sign_extend buf[i] = temp8byte else: - for i in range(numberOfRecords): - memcpy(&temp7, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp7, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) temp8byte = temp7[0]<<48 | temp7[1]<<40 | temp7[2]<<32 | \ temp7[3]<<24 | temp7[4]<<16 | temp7[5]<<8 | temp7[6] # swap bytes # right shift - if bitOffset > 0: - temp8byte = temp8byte >> bitOffset + if bit_offset > 0: + temp8byte = temp8byte >> bit_offset # mask left part - if bitCount < 56: + if bit_count < 56: temp8byte &= mask - signBit = temp8byte & signBitMask - if signBit: # negative value, sign extend - temp8byte |= signExtend + sign_bit = temp8byte & sign_bit_mask + if sign_bit: # negative value, sign extend + temp8byte |= sign_extend buf[i] = temp8byte - elif nBytes == 6: + elif n_bytes == 6: if swap == 0: - for i in range(numberOfRecords): - memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # right shift - if bitOffset > 0: - temp8byte = temp8byte >> bitOffset + if bit_offset > 0: + temp8byte = temp8byte >> bit_offset # mask left part - if bitCount < 48: + if bit_count < 48: temp8byte &= mask - signBit = temp8byte & signBitMask - if signBit: # negative value, sign extend - temp8byte |= signExtend + sign_bit = temp8byte & sign_bit_mask + if sign_bit: # negative value, sign extend + temp8byte |= sign_extend buf[i] = temp8byte else: - for i in range(numberOfRecords): - memcpy(&temp6, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp6, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) temp8byte = temp6[0]<<40 | temp6[1]<<32 | temp6[2]<<24 | \ temp6[3]<<16 | temp6[4]<<8 | temp6[5] # swap bytes # right shift - if bitOffset > 0: - temp8byte = temp8byte >> bitOffset + if bit_offset > 0: + temp8byte = temp8byte >> bit_offset # mask left part - if bitCount < 48: + if bit_count < 48: temp8byte &= mask - signBit = temp8byte & signBitMask - if signBit: # negative value, sign extend - temp8byte |= signExtend + sign_bit = temp8byte & sign_bit_mask + if sign_bit: # negative value, sign extend + temp8byte |= sign_extend buf[i] = temp8byte - elif nBytes == 5: + elif n_bytes == 5: if swap == 0: - for i in range(numberOfRecords): - memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # right shift - if bitOffset > 0: - temp8byte = temp8byte >> bitOffset + if bit_offset > 0: + temp8byte = temp8byte >> bit_offset # mask left part - if bitCount < 40: + if bit_count < 40: temp8byte &= mask - signBit = temp8byte & signBitMask - if signBit: # negative value, sign extend - temp8byte |= signExtend + sign_bit = temp8byte & sign_bit_mask + if sign_bit: # negative value, sign extend + temp8byte |= sign_extend buf[i] = temp8byte else: - for i in range(numberOfRecords): - memcpy(&temp5, &bita[posByteBeg + record_byte_size * i], nBytes) + for i in range(number_of_records): + memcpy(&temp5, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) temp8byte = temp5[0]<<32 | temp5[1]<<24 | \ temp5[2]<<16 | temp5[3]<<8 | temp5[4] # swap bytes # right shift - if bitOffset > 0: - temp8byte = temp8byte >> bitOffset + if bit_offset > 0: + temp8byte = temp8byte >> bit_offset # mask left part - if bitCount < 40: + if bit_count < 40: temp8byte &= mask - signBit = temp8byte & signBitMask - if signBit: # negative value, sign extend - temp8byte |= signExtend + sign_bit = temp8byte & sign_bit_mask + if sign_bit: # negative value, sign extend + temp8byte |= sign_extend buf[i] = temp8byte return buf -cdef inline dataReadByte(const char* bita, str RecordFormat, unsigned long long numberOfRecords, - unsigned long record_byte_size, unsigned long posByteBeg, unsigned long nBytes, - unsigned long bitCount, unsigned char bitOffset): - cdef np.ndarray buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array +cdef inline read_byte(const char* bit_stream, str record_format, unsigned long long number_of_records, + unsigned long record_byte_size, unsigned long pos_byte_beg, unsigned long n_bytes, + unsigned long bit_count, unsigned char bit_offset): + cdef np.ndarray buf = np.empty(number_of_records, dtype=record_format) # return numpy array cdef unsigned long long i - cdef unsigned long posByteEnd = posByteBeg + nBytes - for i in range(numberOfRecords): - buf[i] = bytes(bita[posByteBeg + record_byte_size * i:\ - posByteEnd + record_byte_size * i]) + cdef unsigned long pos_byte_end = pos_byte_beg + n_bytes + for i in range(number_of_records): + buf[i] = bytes(bit_stream[pos_byte_beg + record_byte_size * i:\ + pos_byte_end + record_byte_size * i]) return buf -cdef inline dataReadArray(const char* bita, str RecordFormat, unsigned long long numberOfRecords, - unsigned long record_byte_size, unsigned long posByteBeg, unsigned long nBytes, - unsigned long bitCount, unsigned char bitOffset, unsigned char swap): - cdef np.ndarray buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array +cdef inline read_array(const char* bit_stream, str record_format, unsigned long long number_of_records, + unsigned long record_byte_size, unsigned long pos_byte_beg, unsigned long n_bytes, + unsigned long bit_count, unsigned char bit_offset, unsigned char swap): + cdef np.ndarray buf = np.empty(number_of_records, dtype=record_format) # return numpy array cdef unsigned long long i - cdef unsigned long posByteEnd = posByteBeg + nBytes - for i in range(numberOfRecords): - buf[i] = np.fromstring(bita[posByteBeg + record_byte_size * i:\ - posByteEnd + record_byte_size * i], dtype=RecordFormat) + cdef unsigned long pos_byte_end = pos_byte_beg + n_bytes + for i in range(number_of_records): + buf[i] = np.fromstring(bit_stream[pos_byte_beg + record_byte_size * i:\ + pos_byte_end + record_byte_size * i], dtype=record_format) if swap == 0: return buf else: diff --git a/mdfreader/mdf3reader.py b/mdfreader/mdf3reader.py index 1b740e4..fb03605 100644 --- a/mdfreader/mdf3reader.py +++ b/mdfreader/mdf3reader.py @@ -518,7 +518,7 @@ def read_sorted_record(self, fid, pointer, channel_set=None): rec = recarray(self.numberOfRecords, dtype={'names': data_record_name, 'formats': numpy_data_record_format}) try: # use rather cython compiled code for performance - from dataRead import dataRead + from dataRead import data_read # converts data type from mdf 3.x to 4.x convertDataType3to4 = {0: 0, 1: 2, 2: 4, 3: 4, 7: 6, 8: 10, @@ -528,15 +528,15 @@ def read_sorted_record(self, fid, pointer, channel_set=None): bit_stream = fid.read(chunk_size) for id, chan in enumerate(rec_chan): rec[chan.name][previous_index: previous_index + n_record_chunk] = \ - dataRead(bytes(bit_stream), - chan.bitCount, - convertDataType3to4[chan.signalDataType], - chan.nativedataFormat, - n_record_chunk, - self.CGrecordLength, - chan.bitOffset, - chan.posByteBeg, - chan.nBytes, 0) + data_read(bytes(bit_stream), + chan.bitCount, + convertDataType3to4[chan.signalDataType], + chan.nativedataFormat, + n_record_chunk, + self.CGrecordLength, + chan.bitOffset, + chan.posByteBeg, + chan.nBytes, 0) # masking already considered in dataRead self[rec_chan[id].channelNumber].bit_masking_needed = False previous_index += n_record_chunk diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index 0be48cf..a140767 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -52,7 +52,7 @@ conversionField, idField, invalidPosField, CompressedData from .channel import Channel4 try: - from dataRead import dataRead + from dataRead import data_read dataRead_available = True except ImportError: warn('dataRead cannot be imported, compile it with Cython', ImportWarning) @@ -967,12 +967,12 @@ def read_channels_from_bytes(self, bit_stream, info, channel_set=None, n_records else: array_flag = 0 buf[self[chan].name] = \ - dataRead(bytesdata, self[chan].bit_count(info), - self[chan].signal_data_type(info), - self[chan].native_data_format(info), - n_records, self.CGrecordLength, - self[chan].bit_offset(info), self[chan].pos_byte_beg(info), - self[chan].nBytes, array_flag) + data_read(bytesdata, self[chan].bit_count(info), + self[chan].signal_data_type(info), + self[chan].native_data_format(info), + n_records, self.CGrecordLength, + self[chan].bit_offset(info), self[chan].pos_byte_beg(info), + self[chan].nBytes, array_flag) return buf else: return self.read_channels_from_bytes_fallback(bit_stream, info, channel_set, n_records, dtype) From f38a96d7650a7d3d908afa92031cb95d6a3d5129 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Thu, 1 Nov 2018 18:39:08 +0100 Subject: [PATCH 47/61] Some pep8 refactoring --- dataRead.c | 4802 ++++++++++++++++++++------------------- mdfreader/mdf.py | 30 +- mdfreader/mdf3reader.py | 16 +- mdfreader/mdf4reader.py | 167 +- mdfreader/mdfreader.py | 30 +- 5 files changed, 2550 insertions(+), 2495 deletions(-) diff --git a/dataRead.c b/dataRead.c index 8959513..2b3e417 100644 --- a/dataRead.c +++ b/dataRead.c @@ -1,5 +1,18 @@ /* Generated by Cython 0.28.4 */ +/* BEGIN: Cython Metadata +{ + "distutils": { + "depends": [], + "name": "dataRead", + "sources": [ + "dataRead.pyx" + ] + }, + "module_name": "dataRead" +} +END: Cython Metadata */ + #define PY_SSIZE_T_CLEAN #include "Python.h" #ifndef Py_PYTHON_H @@ -1614,18 +1627,18 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, cha /* Module declarations from 'cpython.bytes' */ /* Module declarations from 'dataRead' */ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadFloat(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned char); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadDouble(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned char); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUChar(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadChar(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUShort(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char, unsigned char); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadShort(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char, unsigned char); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char, unsigned long, unsigned char); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char, unsigned long, unsigned char); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char, unsigned long, unsigned char); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char, unsigned long, unsigned char); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadByte(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned long, unsigned char); /*proto*/ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned long, unsigned char, unsigned char); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_float(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned char); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_double(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned char); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_unsigned_char(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_signed_char(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_unsigned_short(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char, unsigned char); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_signed_short(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char, unsigned char); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_unsigned_int(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char, unsigned long, unsigned char); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_signed_int(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char, unsigned long, unsigned char); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_unsigned_longlong(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char, unsigned long, unsigned char); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_signed_longlong(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned char, unsigned long, unsigned char); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_byte(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned long, unsigned char); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_array(char const *, PyObject *, unsigned PY_LONG_LONG, unsigned long, unsigned long, unsigned long, unsigned long, unsigned char, unsigned char); /*proto*/ static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t = { "float32_t", NULL, sizeof(__pyx_t_5numpy_float32_t), { 0 }, 0, 'R', 0, 0 }; static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t = { "float64_t", NULL, sizeof(__pyx_t_5numpy_float64_t), { 0 }, 0, 'R', 0, 0 }; static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_uint8_t = { "uint8_t", NULL, sizeof(__pyx_t_5numpy_uint8_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_uint8_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_uint8_t), 0 }; @@ -1651,7 +1664,6 @@ static const char __pyx_k_np[] = "np"; static const char __pyx_k_big[] = "big"; static const char __pyx_k_sys[] = "sys"; static const char __pyx_k_tmp[] = "tmp"; -static const char __pyx_k_bita[] = "bita"; static const char __pyx_k_main[] = "__main__"; static const char __pyx_k_test[] = "__test__"; static const char __pyx_k_array[] = "array"; @@ -1661,22 +1673,24 @@ static const char __pyx_k_numpy[] = "numpy"; static const char __pyx_k_range[] = "range"; static const char __pyx_k_import[] = "__import__"; static const char __pyx_k_little[] = "little"; -static const char __pyx_k_nBytes[] = "nBytes"; -static const char __pyx_k_bitCount[] = "bitCount"; +static const char __pyx_k_n_bytes[] = "n_bytes"; static const char __pyx_k_byteswap[] = "byteswap"; static const char __pyx_k_dataRead[] = "dataRead"; -static const char __pyx_k_bitOffset[] = "bitOffset"; +static const char __pyx_k_bit_count[] = "bit_count"; static const char __pyx_k_byteorder[] = "byteorder"; +static const char __pyx_k_data_read[] = "data_read"; static const char __pyx_k_ValueError[] = "ValueError"; +static const char __pyx_k_bit_offset[] = "bit_offset"; +static const char __pyx_k_bit_stream[] = "bit_stream"; static const char __pyx_k_fromstring[] = "fromstring"; -static const char __pyx_k_posByteBeg[] = "posByteBeg"; static const char __pyx_k_ImportError[] = "ImportError"; -static const char __pyx_k_RecordFormat[] = "RecordFormat"; static const char __pyx_k_RuntimeError[] = "RuntimeError"; static const char __pyx_k_dataRead_pyx[] = "dataRead.pyx"; -static const char __pyx_k_signalDataType[] = "signalDataType"; -static const char __pyx_k_numberOfRecords[] = "numberOfRecords"; +static const char __pyx_k_pos_byte_beg[] = "pos_byte_beg"; +static const char __pyx_k_record_format[] = "record_format"; static const char __pyx_k_record_byte_size[] = "record_byte_size"; +static const char __pyx_k_signal_data_type[] = "signal_data_type"; +static const char __pyx_k_number_of_records[] = "number_of_records"; static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; static const char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous"; static const char __pyx_k_numpy_core_multiarray_failed_to[] = "numpy.core.multiarray failed to import"; @@ -1690,44 +1704,45 @@ static PyObject *__pyx_kp_u_Format_string_allocated_too_shor; static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2; static PyObject *__pyx_n_s_ImportError; static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor; -static PyObject *__pyx_n_s_RecordFormat; static PyObject *__pyx_n_s_RuntimeError; static PyObject *__pyx_n_s_S; static PyObject *__pyx_n_s_V; static PyObject *__pyx_n_s_ValueError; static PyObject *__pyx_n_s_array; static PyObject *__pyx_n_s_big; -static PyObject *__pyx_n_s_bitCount; -static PyObject *__pyx_n_s_bitOffset; -static PyObject *__pyx_n_s_bita; +static PyObject *__pyx_n_s_bit_count; +static PyObject *__pyx_n_s_bit_offset; +static PyObject *__pyx_n_s_bit_stream; static PyObject *__pyx_n_s_byteorder; static PyObject *__pyx_n_s_byteswap; static PyObject *__pyx_n_s_cline_in_traceback; static PyObject *__pyx_n_s_dataRead; static PyObject *__pyx_kp_s_dataRead_pyx; +static PyObject *__pyx_n_s_data_read; static PyObject *__pyx_n_s_dtype; static PyObject *__pyx_n_s_empty; static PyObject *__pyx_n_s_fromstring; static PyObject *__pyx_n_s_import; static PyObject *__pyx_n_s_little; static PyObject *__pyx_n_s_main; -static PyObject *__pyx_n_s_nBytes; +static PyObject *__pyx_n_s_n_bytes; static PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous; static PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou; static PyObject *__pyx_n_s_np; -static PyObject *__pyx_n_s_numberOfRecords; +static PyObject *__pyx_n_s_number_of_records; static PyObject *__pyx_n_s_numpy; static PyObject *__pyx_kp_s_numpy_core_multiarray_failed_to; static PyObject *__pyx_kp_s_numpy_core_umath_failed_to_impor; -static PyObject *__pyx_n_s_posByteBeg; +static PyObject *__pyx_n_s_pos_byte_beg; static PyObject *__pyx_n_s_range; static PyObject *__pyx_n_s_record_byte_size; -static PyObject *__pyx_n_s_signalDataType; +static PyObject *__pyx_n_s_record_format; +static PyObject *__pyx_n_s_signal_data_type; static PyObject *__pyx_n_s_sys; static PyObject *__pyx_n_s_test; static PyObject *__pyx_n_s_tmp; static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd; -static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_tmp, unsigned short __pyx_v_bitCount, unsigned short __pyx_v_signalDataType, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned char __pyx_v_bitOffset, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_nBytes, PyObject *__pyx_v_array); /* proto */ +static PyObject *__pyx_pf_8dataRead_data_read(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_tmp, unsigned short __pyx_v_bit_count, unsigned short __pyx_v_signal_data_type, PyObject *__pyx_v_record_format, unsigned PY_LONG_LONG __pyx_v_number_of_records, unsigned long __pyx_v_record_byte_size, unsigned char __pyx_v_bit_offset, unsigned long __pyx_v_pos_byte_beg, unsigned long __pyx_v_n_bytes, PyObject *__pyx_v_array); /* proto */ static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */ static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */ static PyObject *__pyx_tuple_; @@ -1746,31 +1761,31 @@ static PyObject *__pyx_codeobj__11; /* "dataRead.pyx":11 * #@cython.boundscheck(False) * #@cython.wraparound(False) - * def dataRead(bytes tmp, unsigned short bitCount, # <<<<<<<<<<<<<< - * unsigned short signalDataType, str RecordFormat, unsigned long long numberOfRecords, - * unsigned long record_byte_size, unsigned char bitOffset, + * def data_read(bytes tmp, unsigned short bit_count, # <<<<<<<<<<<<<< + * unsigned short signal_data_type, str record_format, unsigned long long number_of_records, + * unsigned long record_byte_size, unsigned char bit_offset, */ /* Python wrapper */ -static PyObject *__pyx_pw_8dataRead_1dataRead(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_8dataRead_dataRead[] = "dataRead function to read in cython a channel from a byte stream\n\n Parameters\n ------------\n tmp : bytes\n byte stream\n bitCount : unsigned short\n number of bit taken by the channel in the record\n signalDataType : unsigned short\n int to describe data type\n RecordFormat : string\n basic numpy dtype description of data type, used to create\n\t returned numpy ndarray\n numberOfRecords : unsigned long long\n number of records in byte stream\n record_byte_size : unsigned long\n number of bytes taken by one record repeated in byte stream\n bitOffset : unsigned char\n bit offset of data in C aligned bytes\n posByteBeg : unsigned long\n beginning byte position of channel in record\n nBytes : unsigned long\n bytes length of channel in record\n array : boolean\n reads an array, not a vector\n\n Return\n -------\n ndarray of type RecordFormat with numberOfRecords records.\n Byte order is swapped if necessary to match machine byte order before bits offset and masking\n "; -static PyMethodDef __pyx_mdef_8dataRead_1dataRead = {"dataRead", (PyCFunction)__pyx_pw_8dataRead_1dataRead, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8dataRead_dataRead}; -static PyObject *__pyx_pw_8dataRead_1dataRead(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { +static PyObject *__pyx_pw_8dataRead_1data_read(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_8dataRead_data_read[] = "dataRead function to read in cython a channel from a byte stream\n\n Parameters\n ------------\n tmp : bytes\n byte stream\n bit_count : unsigned short\n number of bit taken by the channel in the record\n signal_data_type : unsigned short\n int to describe data type\n record_format : string\n basic numpy dtype description of data type, used to create\n returned numpy ndarray\n number_of_records : unsigned long long\n number of records in byte stream\n record_byte_size : unsigned long\n number of bytes taken by one record repeated in byte stream\n bit_offset : unsigned char\n bit offset of data in C aligned bytes\n pos_byte_beg : unsigned long\n beginning byte position of channel in record\n n_bytes : unsigned long\n bytes length of channel in record\n array : boolean\n reads an array, not a vector\n\n Returns\n -------\n ndarray of type record_format with number_of_records records.\n Byte order is swapped if necessary to match machine byte order before bits offset and masking\n "; +static PyMethodDef __pyx_mdef_8dataRead_1data_read = {"data_read", (PyCFunction)__pyx_pw_8dataRead_1data_read, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8dataRead_data_read}; +static PyObject *__pyx_pw_8dataRead_1data_read(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_tmp = 0; - unsigned short __pyx_v_bitCount; - unsigned short __pyx_v_signalDataType; - PyObject *__pyx_v_RecordFormat = 0; - unsigned PY_LONG_LONG __pyx_v_numberOfRecords; + unsigned short __pyx_v_bit_count; + unsigned short __pyx_v_signal_data_type; + PyObject *__pyx_v_record_format = 0; + unsigned PY_LONG_LONG __pyx_v_number_of_records; unsigned long __pyx_v_record_byte_size; - unsigned char __pyx_v_bitOffset; - unsigned long __pyx_v_posByteBeg; - unsigned long __pyx_v_nBytes; + unsigned char __pyx_v_bit_offset; + unsigned long __pyx_v_pos_byte_beg; + unsigned long __pyx_v_n_bytes; PyObject *__pyx_v_array = 0; PyObject *__pyx_r = 0; __Pyx_RefNannyDeclarations - __Pyx_RefNannySetupContext("dataRead (wrapper)", 0); + __Pyx_RefNannySetupContext("data_read (wrapper)", 0); { - static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_tmp,&__pyx_n_s_bitCount,&__pyx_n_s_signalDataType,&__pyx_n_s_RecordFormat,&__pyx_n_s_numberOfRecords,&__pyx_n_s_record_byte_size,&__pyx_n_s_bitOffset,&__pyx_n_s_posByteBeg,&__pyx_n_s_nBytes,&__pyx_n_s_array,0}; + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_tmp,&__pyx_n_s_bit_count,&__pyx_n_s_signal_data_type,&__pyx_n_s_record_format,&__pyx_n_s_number_of_records,&__pyx_n_s_record_byte_size,&__pyx_n_s_bit_offset,&__pyx_n_s_pos_byte_beg,&__pyx_n_s_n_bytes,&__pyx_n_s_array,0}; PyObject* values[10] = {0,0,0,0,0,0,0,0,0,0}; if (unlikely(__pyx_kwds)) { Py_ssize_t kw_args; @@ -1806,61 +1821,61 @@ static PyObject *__pyx_pw_8dataRead_1dataRead(PyObject *__pyx_self, PyObject *__ else goto __pyx_L5_argtuple_error; CYTHON_FALLTHROUGH; case 1: - if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_bitCount)) != 0)) kw_args--; + if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_bit_count)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("dataRead", 1, 10, 10, 1); __PYX_ERR(0, 11, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("data_read", 1, 10, 10, 1); __PYX_ERR(0, 11, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 2: - if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_signalDataType)) != 0)) kw_args--; + if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_signal_data_type)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("dataRead", 1, 10, 10, 2); __PYX_ERR(0, 11, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("data_read", 1, 10, 10, 2); __PYX_ERR(0, 11, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 3: - if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_RecordFormat)) != 0)) kw_args--; + if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_record_format)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("dataRead", 1, 10, 10, 3); __PYX_ERR(0, 11, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("data_read", 1, 10, 10, 3); __PYX_ERR(0, 11, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 4: - if (likely((values[4] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_numberOfRecords)) != 0)) kw_args--; + if (likely((values[4] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_number_of_records)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("dataRead", 1, 10, 10, 4); __PYX_ERR(0, 11, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("data_read", 1, 10, 10, 4); __PYX_ERR(0, 11, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 5: if (likely((values[5] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_record_byte_size)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("dataRead", 1, 10, 10, 5); __PYX_ERR(0, 11, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("data_read", 1, 10, 10, 5); __PYX_ERR(0, 11, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 6: - if (likely((values[6] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_bitOffset)) != 0)) kw_args--; + if (likely((values[6] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_bit_offset)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("dataRead", 1, 10, 10, 6); __PYX_ERR(0, 11, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("data_read", 1, 10, 10, 6); __PYX_ERR(0, 11, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 7: - if (likely((values[7] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_posByteBeg)) != 0)) kw_args--; + if (likely((values[7] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pos_byte_beg)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("dataRead", 1, 10, 10, 7); __PYX_ERR(0, 11, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("data_read", 1, 10, 10, 7); __PYX_ERR(0, 11, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 8: - if (likely((values[8] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_nBytes)) != 0)) kw_args--; + if (likely((values[8] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_n_bytes)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("dataRead", 1, 10, 10, 8); __PYX_ERR(0, 11, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("data_read", 1, 10, 10, 8); __PYX_ERR(0, 11, __pyx_L3_error) } CYTHON_FALLTHROUGH; case 9: if (likely((values[9] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_array)) != 0)) kw_args--; else { - __Pyx_RaiseArgtupleInvalid("dataRead", 1, 10, 10, 9); __PYX_ERR(0, 11, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("data_read", 1, 10, 10, 9); __PYX_ERR(0, 11, __pyx_L3_error) } } if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "dataRead") < 0)) __PYX_ERR(0, 11, __pyx_L3_error) + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "data_read") < 0)) __PYX_ERR(0, 11, __pyx_L3_error) } } else if (PyTuple_GET_SIZE(__pyx_args) != 10) { goto __pyx_L5_argtuple_error; @@ -1877,27 +1892,27 @@ static PyObject *__pyx_pw_8dataRead_1dataRead(PyObject *__pyx_self, PyObject *__ values[9] = PyTuple_GET_ITEM(__pyx_args, 9); } __pyx_v_tmp = ((PyObject*)values[0]); - __pyx_v_bitCount = __Pyx_PyInt_As_unsigned_short(values[1]); if (unlikely((__pyx_v_bitCount == (unsigned short)-1) && PyErr_Occurred())) __PYX_ERR(0, 11, __pyx_L3_error) - __pyx_v_signalDataType = __Pyx_PyInt_As_unsigned_short(values[2]); if (unlikely((__pyx_v_signalDataType == (unsigned short)-1) && PyErr_Occurred())) __PYX_ERR(0, 12, __pyx_L3_error) - __pyx_v_RecordFormat = ((PyObject*)values[3]); - __pyx_v_numberOfRecords = __Pyx_PyInt_As_unsigned_PY_LONG_LONG(values[4]); if (unlikely((__pyx_v_numberOfRecords == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) __PYX_ERR(0, 12, __pyx_L3_error) + __pyx_v_bit_count = __Pyx_PyInt_As_unsigned_short(values[1]); if (unlikely((__pyx_v_bit_count == (unsigned short)-1) && PyErr_Occurred())) __PYX_ERR(0, 11, __pyx_L3_error) + __pyx_v_signal_data_type = __Pyx_PyInt_As_unsigned_short(values[2]); if (unlikely((__pyx_v_signal_data_type == (unsigned short)-1) && PyErr_Occurred())) __PYX_ERR(0, 12, __pyx_L3_error) + __pyx_v_record_format = ((PyObject*)values[3]); + __pyx_v_number_of_records = __Pyx_PyInt_As_unsigned_PY_LONG_LONG(values[4]); if (unlikely((__pyx_v_number_of_records == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())) __PYX_ERR(0, 12, __pyx_L3_error) __pyx_v_record_byte_size = __Pyx_PyInt_As_unsigned_long(values[5]); if (unlikely((__pyx_v_record_byte_size == (unsigned long)-1) && PyErr_Occurred())) __PYX_ERR(0, 13, __pyx_L3_error) - __pyx_v_bitOffset = __Pyx_PyInt_As_unsigned_char(values[6]); if (unlikely((__pyx_v_bitOffset == (unsigned char)-1) && PyErr_Occurred())) __PYX_ERR(0, 13, __pyx_L3_error) - __pyx_v_posByteBeg = __Pyx_PyInt_As_unsigned_long(values[7]); if (unlikely((__pyx_v_posByteBeg == (unsigned long)-1) && PyErr_Occurred())) __PYX_ERR(0, 14, __pyx_L3_error) - __pyx_v_nBytes = __Pyx_PyInt_As_unsigned_long(values[8]); if (unlikely((__pyx_v_nBytes == (unsigned long)-1) && PyErr_Occurred())) __PYX_ERR(0, 14, __pyx_L3_error) + __pyx_v_bit_offset = __Pyx_PyInt_As_unsigned_char(values[6]); if (unlikely((__pyx_v_bit_offset == (unsigned char)-1) && PyErr_Occurred())) __PYX_ERR(0, 13, __pyx_L3_error) + __pyx_v_pos_byte_beg = __Pyx_PyInt_As_unsigned_long(values[7]); if (unlikely((__pyx_v_pos_byte_beg == (unsigned long)-1) && PyErr_Occurred())) __PYX_ERR(0, 14, __pyx_L3_error) + __pyx_v_n_bytes = __Pyx_PyInt_As_unsigned_long(values[8]); if (unlikely((__pyx_v_n_bytes == (unsigned long)-1) && PyErr_Occurred())) __PYX_ERR(0, 14, __pyx_L3_error) __pyx_v_array = values[9]; } goto __pyx_L4_argument_unpacking_done; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("dataRead", 1, 10, 10, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 11, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("data_read", 1, 10, 10, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 11, __pyx_L3_error) __pyx_L3_error:; - __Pyx_AddTraceback("dataRead.dataRead", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("dataRead.data_read", __pyx_clineno, __pyx_lineno, __pyx_filename); __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_tmp), (&PyBytes_Type), 1, "tmp", 1))) __PYX_ERR(0, 11, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_RecordFormat), (&PyString_Type), 1, "RecordFormat", 1))) __PYX_ERR(0, 12, __pyx_L1_error) - __pyx_r = __pyx_pf_8dataRead_dataRead(__pyx_self, __pyx_v_tmp, __pyx_v_bitCount, __pyx_v_signalDataType, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_bitOffset, __pyx_v_posByteBeg, __pyx_v_nBytes, __pyx_v_array); + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_record_format), (&PyString_Type), 1, "record_format", 1))) __PYX_ERR(0, 12, __pyx_L1_error) + __pyx_r = __pyx_pf_8dataRead_data_read(__pyx_self, __pyx_v_tmp, __pyx_v_bit_count, __pyx_v_signal_data_type, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_bit_offset, __pyx_v_pos_byte_beg, __pyx_v_n_bytes, __pyx_v_array); /* function exit code */ goto __pyx_L0; @@ -1908,8 +1923,8 @@ static PyObject *__pyx_pw_8dataRead_1dataRead(PyObject *__pyx_self, PyObject *__ return __pyx_r; } -static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_tmp, unsigned short __pyx_v_bitCount, unsigned short __pyx_v_signalDataType, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned char __pyx_v_bitOffset, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_nBytes, PyObject *__pyx_v_array) { - char *__pyx_v_bita; +static PyObject *__pyx_pf_8dataRead_data_read(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_tmp, unsigned short __pyx_v_bit_count, unsigned short __pyx_v_signal_data_type, PyObject *__pyx_v_record_format, unsigned PY_LONG_LONG __pyx_v_number_of_records, unsigned long __pyx_v_record_byte_size, unsigned char __pyx_v_bit_offset, unsigned long __pyx_v_pos_byte_beg, unsigned long __pyx_v_n_bytes, PyObject *__pyx_v_array) { + char *__pyx_v_bit_stream; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations char *__pyx_t_1; @@ -1917,51 +1932,51 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_t_3; int __pyx_t_4; PyObject *__pyx_t_5 = NULL; - __Pyx_RefNannySetupContext("dataRead", 0); + __Pyx_RefNannySetupContext("data_read", 0); /* "dataRead.pyx":46 * Byte order is swapped if necessary to match machine byte order before bits offset and masking * """ - * cdef char* bita = PyBytes_AsString(tmp) # <<<<<<<<<<<<<< + * cdef char* bit_stream = PyBytes_AsString(tmp) # <<<<<<<<<<<<<< * if not array: - * if 'V' in RecordFormat or 'S' in RecordFormat or RecordFormat is None: + * if 'V' in record_format or 'S' in record_format or record_format is None: */ __pyx_t_1 = PyBytes_AsString(__pyx_v_tmp); if (unlikely(__pyx_t_1 == ((char *)NULL))) __PYX_ERR(0, 46, __pyx_L1_error) - __pyx_v_bita = __pyx_t_1; + __pyx_v_bit_stream = __pyx_t_1; /* "dataRead.pyx":47 * """ - * cdef char* bita = PyBytes_AsString(tmp) + * cdef char* bit_stream = PyBytes_AsString(tmp) * if not array: # <<<<<<<<<<<<<< - * if 'V' in RecordFormat or 'S' in RecordFormat or RecordFormat is None: - * return dataReadByte(bita, RecordFormat, numberOfRecords, + * if 'V' in record_format or 'S' in record_format or record_format is None: + * return read_byte(bit_stream, record_format, number_of_records, */ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_array); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 47, __pyx_L1_error) __pyx_t_3 = ((!__pyx_t_2) != 0); if (__pyx_t_3) { /* "dataRead.pyx":48 - * cdef char* bita = PyBytes_AsString(tmp) + * cdef char* bit_stream = PyBytes_AsString(tmp) * if not array: - * if 'V' in RecordFormat or 'S' in RecordFormat or RecordFormat is None: # <<<<<<<<<<<<<< - * return dataReadByte(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) + * if 'V' in record_format or 'S' in record_format or record_format is None: # <<<<<<<<<<<<<< + * return read_byte(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset) */ - __pyx_t_2 = (__Pyx_PySequence_ContainsTF(__pyx_n_s_V, __pyx_v_RecordFormat, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 48, __pyx_L1_error) + __pyx_t_2 = (__Pyx_PySequence_ContainsTF(__pyx_n_s_V, __pyx_v_record_format, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 48, __pyx_L1_error) __pyx_t_4 = (__pyx_t_2 != 0); if (!__pyx_t_4) { } else { __pyx_t_3 = __pyx_t_4; goto __pyx_L5_bool_binop_done; } - __pyx_t_4 = (__Pyx_PySequence_ContainsTF(__pyx_n_s_S, __pyx_v_RecordFormat, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 48, __pyx_L1_error) + __pyx_t_4 = (__Pyx_PySequence_ContainsTF(__pyx_n_s_S, __pyx_v_record_format, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 48, __pyx_L1_error) __pyx_t_2 = (__pyx_t_4 != 0); if (!__pyx_t_2) { } else { __pyx_t_3 = __pyx_t_2; goto __pyx_L5_bool_binop_done; } - __pyx_t_2 = (__pyx_v_RecordFormat == ((PyObject*)Py_None)); + __pyx_t_2 = (__pyx_v_record_format == ((PyObject*)Py_None)); __pyx_t_4 = (__pyx_t_2 != 0); __pyx_t_3 = __pyx_t_4; __pyx_L5_bool_binop_done:; @@ -1969,43 +1984,43 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":49 * if not array: - * if 'V' in RecordFormat or 'S' in RecordFormat or RecordFormat is None: - * return dataReadByte(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) - * elif signalDataType in (4, 5) and nBytes == 4: # float + * if 'V' in record_format or 'S' in record_format or record_format is None: + * return read_byte(bit_stream, record_format, number_of_records, # <<<<<<<<<<<<<< + * record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset) + * elif signal_data_type in (4, 5) and n_bytes == 4: # float */ __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":50 - * if 'V' in RecordFormat or 'S' in RecordFormat or RecordFormat is None: - * return dataReadByte(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) # <<<<<<<<<<<<<< - * elif signalDataType in (4, 5) and nBytes == 4: # float - * if (byteorder == 'little' and signalDataType == 4) or \ + * if 'V' in record_format or 'S' in record_format or record_format is None: + * return read_byte(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset) # <<<<<<<<<<<<<< + * elif signal_data_type in (4, 5) and n_bytes == 4: # float + * if (byteorder == 'little' and signal_data_type == 4) or \ */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadByte(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_nBytes, __pyx_v_bitCount, __pyx_v_bitOffset); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 49, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_read_byte(__pyx_v_bit_stream, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_pos_byte_beg, __pyx_v_n_bytes, __pyx_v_bit_count, __pyx_v_bit_offset); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 49, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; /* "dataRead.pyx":48 - * cdef char* bita = PyBytes_AsString(tmp) + * cdef char* bit_stream = PyBytes_AsString(tmp) * if not array: - * if 'V' in RecordFormat or 'S' in RecordFormat or RecordFormat is None: # <<<<<<<<<<<<<< - * return dataReadByte(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) + * if 'V' in record_format or 'S' in record_format or record_format is None: # <<<<<<<<<<<<<< + * return read_byte(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset) */ } /* "dataRead.pyx":51 - * return dataReadByte(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) - * elif signalDataType in (4, 5) and nBytes == 4: # float # <<<<<<<<<<<<<< - * if (byteorder == 'little' and signalDataType == 4) or \ - * (byteorder == 'big' and signalDataType == 5): + * return read_byte(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset) + * elif signal_data_type in (4, 5) and n_bytes == 4: # float # <<<<<<<<<<<<<< + * if (byteorder == 'little' and signal_data_type == 4) or \ + * (byteorder == 'big' and signal_data_type == 5): */ - switch (__pyx_v_signalDataType) { + switch (__pyx_v_signal_data_type) { case 4: case 5: __pyx_t_4 = 1; @@ -2020,17 +2035,17 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_2; goto __pyx_L8_bool_binop_done; } - __pyx_t_2 = ((__pyx_v_nBytes == 4) != 0); + __pyx_t_2 = ((__pyx_v_n_bytes == 4) != 0); __pyx_t_3 = __pyx_t_2; __pyx_L8_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":52 - * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) - * elif signalDataType in (4, 5) and nBytes == 4: # float - * if (byteorder == 'little' and signalDataType == 4) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 5): - * return dataReadFloat(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset) + * elif signal_data_type in (4, 5) and n_bytes == 4: # float + * if (byteorder == 'little' and signal_data_type == 4) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 5): + * return read_float(bit_stream, record_format, number_of_records, */ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 52, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -2040,7 +2055,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, goto __pyx_L12_next_or; } else { } - __pyx_t_2 = ((__pyx_v_signalDataType == 4) != 0); + __pyx_t_2 = ((__pyx_v_signal_data_type == 4) != 0); if (!__pyx_t_2) { } else { __pyx_t_3 = __pyx_t_2; @@ -2049,11 +2064,11 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L12_next_or:; /* "dataRead.pyx":53 - * elif signalDataType in (4, 5) and nBytes == 4: # float - * if (byteorder == 'little' and signalDataType == 4) or \ - * (byteorder == 'big' and signalDataType == 5): # <<<<<<<<<<<<<< - * return dataReadFloat(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, 0) + * elif signal_data_type in (4, 5) and n_bytes == 4: # float + * if (byteorder == 'little' and signal_data_type == 4) or \ + * (byteorder == 'big' and signal_data_type == 5): # <<<<<<<<<<<<<< + * return read_float(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, 0) */ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 53, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -2064,68 +2079,68 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_2; goto __pyx_L11_bool_binop_done; } - __pyx_t_2 = ((__pyx_v_signalDataType == 5) != 0); + __pyx_t_2 = ((__pyx_v_signal_data_type == 5) != 0); __pyx_t_3 = __pyx_t_2; __pyx_L11_bool_binop_done:; /* "dataRead.pyx":52 - * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) - * elif signalDataType in (4, 5) and nBytes == 4: # float - * if (byteorder == 'little' and signalDataType == 4) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 5): - * return dataReadFloat(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset) + * elif signal_data_type in (4, 5) and n_bytes == 4: # float + * if (byteorder == 'little' and signal_data_type == 4) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 5): + * return read_float(bit_stream, record_format, number_of_records, */ if (__pyx_t_3) { /* "dataRead.pyx":54 - * if (byteorder == 'little' and signalDataType == 4) or \ - * (byteorder == 'big' and signalDataType == 5): - * return dataReadFloat(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, 0) + * if (byteorder == 'little' and signal_data_type == 4) or \ + * (byteorder == 'big' and signal_data_type == 5): + * return read_float(bit_stream, record_format, number_of_records, # <<<<<<<<<<<<<< + * record_byte_size, pos_byte_beg, 0) * else: # swap bytes */ __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":55 - * (byteorder == 'big' and signalDataType == 5): - * return dataReadFloat(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, 0) # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 5): + * return read_float(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, 0) # <<<<<<<<<<<<<< * else: # swap bytes - * return dataReadFloat(bita, RecordFormat, numberOfRecords, + * return read_float(bit_stream, record_format, number_of_records, */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadFloat(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 54, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_read_float(__pyx_v_bit_stream, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_pos_byte_beg, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 54, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; /* "dataRead.pyx":52 - * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) - * elif signalDataType in (4, 5) and nBytes == 4: # float - * if (byteorder == 'little' and signalDataType == 4) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 5): - * return dataReadFloat(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset) + * elif signal_data_type in (4, 5) and n_bytes == 4: # float + * if (byteorder == 'little' and signal_data_type == 4) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 5): + * return read_float(bit_stream, record_format, number_of_records, */ } /* "dataRead.pyx":57 - * record_byte_size, posByteBeg, 0) + * record_byte_size, pos_byte_beg, 0) * else: # swap bytes - * return dataReadFloat(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, 1) - * elif signalDataType in (4, 5) and nBytes == 8: # double + * return read_float(bit_stream, record_format, number_of_records, # <<<<<<<<<<<<<< + * record_byte_size, pos_byte_beg, 1) + * elif signal_data_type in (4, 5) and n_bytes == 8: # double */ /*else*/ { __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":58 * else: # swap bytes - * return dataReadFloat(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, 1) # <<<<<<<<<<<<<< - * elif signalDataType in (4, 5) and nBytes == 8: # double - * if (byteorder == 'little' and signalDataType == 4) or \ + * return read_float(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, 1) # <<<<<<<<<<<<<< + * elif signal_data_type in (4, 5) and n_bytes == 8: # double + * if (byteorder == 'little' and signal_data_type == 4) or \ */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadFloat(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 57, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_read_float(__pyx_v_bit_stream, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_pos_byte_beg, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 57, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; @@ -2133,22 +2148,22 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, } /* "dataRead.pyx":51 - * return dataReadByte(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) - * elif signalDataType in (4, 5) and nBytes == 4: # float # <<<<<<<<<<<<<< - * if (byteorder == 'little' and signalDataType == 4) or \ - * (byteorder == 'big' and signalDataType == 5): + * return read_byte(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset) + * elif signal_data_type in (4, 5) and n_bytes == 4: # float # <<<<<<<<<<<<<< + * if (byteorder == 'little' and signal_data_type == 4) or \ + * (byteorder == 'big' and signal_data_type == 5): */ } /* "dataRead.pyx":59 - * return dataReadFloat(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, 1) - * elif signalDataType in (4, 5) and nBytes == 8: # double # <<<<<<<<<<<<<< - * if (byteorder == 'little' and signalDataType == 4) or \ - * (byteorder == 'big' and signalDataType == 5): + * return read_float(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, 1) + * elif signal_data_type in (4, 5) and n_bytes == 8: # double # <<<<<<<<<<<<<< + * if (byteorder == 'little' and signal_data_type == 4) or \ + * (byteorder == 'big' and signal_data_type == 5): */ - switch (__pyx_v_signalDataType) { + switch (__pyx_v_signal_data_type) { case 4: case 5: __pyx_t_2 = 1; @@ -2163,17 +2178,17 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_4; goto __pyx_L15_bool_binop_done; } - __pyx_t_4 = ((__pyx_v_nBytes == 8) != 0); + __pyx_t_4 = ((__pyx_v_n_bytes == 8) != 0); __pyx_t_3 = __pyx_t_4; __pyx_L15_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":60 - * record_byte_size, posByteBeg, 1) - * elif signalDataType in (4, 5) and nBytes == 8: # double - * if (byteorder == 'little' and signalDataType == 4) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 5): - * return dataReadDouble(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, 1) + * elif signal_data_type in (4, 5) and n_bytes == 8: # double + * if (byteorder == 'little' and signal_data_type == 4) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 5): + * return read_double(bit_stream, record_format, number_of_records, */ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 60, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -2183,7 +2198,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, goto __pyx_L19_next_or; } else { } - __pyx_t_4 = ((__pyx_v_signalDataType == 4) != 0); + __pyx_t_4 = ((__pyx_v_signal_data_type == 4) != 0); if (!__pyx_t_4) { } else { __pyx_t_3 = __pyx_t_4; @@ -2192,11 +2207,11 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L19_next_or:; /* "dataRead.pyx":61 - * elif signalDataType in (4, 5) and nBytes == 8: # double - * if (byteorder == 'little' and signalDataType == 4) or \ - * (byteorder == 'big' and signalDataType == 5): # <<<<<<<<<<<<<< - * return dataReadDouble(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, 0) + * elif signal_data_type in (4, 5) and n_bytes == 8: # double + * if (byteorder == 'little' and signal_data_type == 4) or \ + * (byteorder == 'big' and signal_data_type == 5): # <<<<<<<<<<<<<< + * return read_double(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, 0) */ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 61, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -2207,68 +2222,68 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_4; goto __pyx_L18_bool_binop_done; } - __pyx_t_4 = ((__pyx_v_signalDataType == 5) != 0); + __pyx_t_4 = ((__pyx_v_signal_data_type == 5) != 0); __pyx_t_3 = __pyx_t_4; __pyx_L18_bool_binop_done:; /* "dataRead.pyx":60 - * record_byte_size, posByteBeg, 1) - * elif signalDataType in (4, 5) and nBytes == 8: # double - * if (byteorder == 'little' and signalDataType == 4) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 5): - * return dataReadDouble(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, 1) + * elif signal_data_type in (4, 5) and n_bytes == 8: # double + * if (byteorder == 'little' and signal_data_type == 4) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 5): + * return read_double(bit_stream, record_format, number_of_records, */ if (__pyx_t_3) { /* "dataRead.pyx":62 - * if (byteorder == 'little' and signalDataType == 4) or \ - * (byteorder == 'big' and signalDataType == 5): - * return dataReadDouble(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, 0) + * if (byteorder == 'little' and signal_data_type == 4) or \ + * (byteorder == 'big' and signal_data_type == 5): + * return read_double(bit_stream, record_format, number_of_records, # <<<<<<<<<<<<<< + * record_byte_size, pos_byte_beg, 0) * else: # swap bytes */ __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":63 - * (byteorder == 'big' and signalDataType == 5): - * return dataReadDouble(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, 0) # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 5): + * return read_double(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, 0) # <<<<<<<<<<<<<< * else: # swap bytes - * return dataReadDouble(bita, RecordFormat, numberOfRecords, + * return read_double(bit_stream, record_format, number_of_records, */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadDouble(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 62, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_read_double(__pyx_v_bit_stream, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_pos_byte_beg, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 62, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; /* "dataRead.pyx":60 - * record_byte_size, posByteBeg, 1) - * elif signalDataType in (4, 5) and nBytes == 8: # double - * if (byteorder == 'little' and signalDataType == 4) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 5): - * return dataReadDouble(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, 1) + * elif signal_data_type in (4, 5) and n_bytes == 8: # double + * if (byteorder == 'little' and signal_data_type == 4) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 5): + * return read_double(bit_stream, record_format, number_of_records, */ } /* "dataRead.pyx":65 - * record_byte_size, posByteBeg, 0) + * record_byte_size, pos_byte_beg, 0) * else: # swap bytes - * return dataReadDouble(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, 1) - * elif signalDataType in (0, 1, 13) and nBytes == 1: # unsigned char + * return read_double(bit_stream, record_format, number_of_records, # <<<<<<<<<<<<<< + * record_byte_size, pos_byte_beg, 1) + * elif signal_data_type in (0, 1, 13) and n_bytes == 1: # unsigned char */ /*else*/ { __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":66 * else: # swap bytes - * return dataReadDouble(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, 1) # <<<<<<<<<<<<<< - * elif signalDataType in (0, 1, 13) and nBytes == 1: # unsigned char - * return dataReadUChar(bita, RecordFormat, numberOfRecords, + * return read_double(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, 1) # <<<<<<<<<<<<<< + * elif signal_data_type in (0, 1, 13) and n_bytes == 1: # unsigned char + * return read_unsigned_char(bit_stream, record_format, number_of_records, */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadDouble(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 65, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_read_double(__pyx_v_bit_stream, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_pos_byte_beg, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 65, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; @@ -2276,22 +2291,22 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, } /* "dataRead.pyx":59 - * return dataReadFloat(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, 1) - * elif signalDataType in (4, 5) and nBytes == 8: # double # <<<<<<<<<<<<<< - * if (byteorder == 'little' and signalDataType == 4) or \ - * (byteorder == 'big' and signalDataType == 5): + * return read_float(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, 1) + * elif signal_data_type in (4, 5) and n_bytes == 8: # double # <<<<<<<<<<<<<< + * if (byteorder == 'little' and signal_data_type == 4) or \ + * (byteorder == 'big' and signal_data_type == 5): */ } /* "dataRead.pyx":67 - * return dataReadDouble(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, 1) - * elif signalDataType in (0, 1, 13) and nBytes == 1: # unsigned char # <<<<<<<<<<<<<< - * return dataReadUChar(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset) + * return read_double(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, 1) + * elif signal_data_type in (0, 1, 13) and n_bytes == 1: # unsigned char # <<<<<<<<<<<<<< + * return read_unsigned_char(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset) */ - switch (__pyx_v_signalDataType) { + switch (__pyx_v_signal_data_type) { case 0: case 1: case 13: @@ -2307,50 +2322,50 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_2; goto __pyx_L22_bool_binop_done; } - __pyx_t_2 = ((__pyx_v_nBytes == 1) != 0); + __pyx_t_2 = ((__pyx_v_n_bytes == 1) != 0); __pyx_t_3 = __pyx_t_2; __pyx_L22_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":68 - * record_byte_size, posByteBeg, 1) - * elif signalDataType in (0, 1, 13) and nBytes == 1: # unsigned char - * return dataReadUChar(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (2, 3) and nBytes == 1: # signed char + * record_byte_size, pos_byte_beg, 1) + * elif signal_data_type in (0, 1, 13) and n_bytes == 1: # unsigned char + * return read_unsigned_char(bit_stream, record_format, number_of_records, # <<<<<<<<<<<<<< + * record_byte_size, pos_byte_beg, bit_count, bit_offset) + * elif signal_data_type in (2, 3) and n_bytes == 1: # signed char */ __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":69 - * elif signalDataType in (0, 1, 13) and nBytes == 1: # unsigned char - * return dataReadUChar(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset) # <<<<<<<<<<<<<< - * elif signalDataType in (2, 3) and nBytes == 1: # signed char - * return dataReadChar(bita, RecordFormat, numberOfRecords, + * elif signal_data_type in (0, 1, 13) and n_bytes == 1: # unsigned char + * return read_unsigned_char(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset) # <<<<<<<<<<<<<< + * elif signal_data_type in (2, 3) and n_bytes == 1: # signed char + * return read_signed_char(bit_stream, record_format, number_of_records, */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadUChar(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 68, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_read_unsigned_char(__pyx_v_bit_stream, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_pos_byte_beg, __pyx_v_bit_count, __pyx_v_bit_offset); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 68, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; /* "dataRead.pyx":67 - * return dataReadDouble(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, 1) - * elif signalDataType in (0, 1, 13) and nBytes == 1: # unsigned char # <<<<<<<<<<<<<< - * return dataReadUChar(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset) + * return read_double(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, 1) + * elif signal_data_type in (0, 1, 13) and n_bytes == 1: # unsigned char # <<<<<<<<<<<<<< + * return read_unsigned_char(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset) */ } /* "dataRead.pyx":70 - * return dataReadUChar(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (2, 3) and nBytes == 1: # signed char # <<<<<<<<<<<<<< - * return dataReadChar(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset) + * return read_unsigned_char(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset) + * elif signal_data_type in (2, 3) and n_bytes == 1: # signed char # <<<<<<<<<<<<<< + * return read_signed_char(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset) */ - switch (__pyx_v_signalDataType) { + switch (__pyx_v_signal_data_type) { case 2: case 3: __pyx_t_2 = 1; @@ -2365,50 +2380,50 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_4; goto __pyx_L24_bool_binop_done; } - __pyx_t_4 = ((__pyx_v_nBytes == 1) != 0); + __pyx_t_4 = ((__pyx_v_n_bytes == 1) != 0); __pyx_t_3 = __pyx_t_4; __pyx_L24_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":71 - * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (2, 3) and nBytes == 1: # signed char - * return dataReadChar(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (0, 1, 13, 14) and nBytes <= 2: # unsigned short + * record_byte_size, pos_byte_beg, bit_count, bit_offset) + * elif signal_data_type in (2, 3) and n_bytes == 1: # signed char + * return read_signed_char(bit_stream, record_format, number_of_records, # <<<<<<<<<<<<<< + * record_byte_size, pos_byte_beg, bit_count, bit_offset) + * elif signal_data_type in (0, 1, 13, 14) and n_bytes <= 2: # unsigned short */ __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":72 - * elif signalDataType in (2, 3) and nBytes == 1: # signed char - * return dataReadChar(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset) # <<<<<<<<<<<<<< - * elif signalDataType in (0, 1, 13, 14) and nBytes <= 2: # unsigned short - * if (byteorder == 'little' and signalDataType == 0) or \ + * elif signal_data_type in (2, 3) and n_bytes == 1: # signed char + * return read_signed_char(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset) # <<<<<<<<<<<<<< + * elif signal_data_type in (0, 1, 13, 14) and n_bytes <= 2: # unsigned short + * if (byteorder == 'little' and signal_data_type == 0) or \ */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadChar(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 71, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_read_signed_char(__pyx_v_bit_stream, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_pos_byte_beg, __pyx_v_bit_count, __pyx_v_bit_offset); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 71, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; /* "dataRead.pyx":70 - * return dataReadUChar(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (2, 3) and nBytes == 1: # signed char # <<<<<<<<<<<<<< - * return dataReadChar(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset) + * return read_unsigned_char(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset) + * elif signal_data_type in (2, 3) and n_bytes == 1: # signed char # <<<<<<<<<<<<<< + * return read_signed_char(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset) */ } /* "dataRead.pyx":73 - * return dataReadChar(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (0, 1, 13, 14) and nBytes <= 2: # unsigned short # <<<<<<<<<<<<<< - * if (byteorder == 'little' and signalDataType == 0) or \ - * (byteorder == 'big' and signalDataType == 1): + * return read_signed_char(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset) + * elif signal_data_type in (0, 1, 13, 14) and n_bytes <= 2: # unsigned short # <<<<<<<<<<<<<< + * if (byteorder == 'little' and signal_data_type == 0) or \ + * (byteorder == 'big' and signal_data_type == 1): */ - switch (__pyx_v_signalDataType) { + switch (__pyx_v_signal_data_type) { case 0: case 1: case 13: @@ -2425,17 +2440,17 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_2; goto __pyx_L26_bool_binop_done; } - __pyx_t_2 = ((__pyx_v_nBytes <= 2) != 0); + __pyx_t_2 = ((__pyx_v_n_bytes <= 2) != 0); __pyx_t_3 = __pyx_t_2; __pyx_L26_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":74 - * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (0, 1, 13, 14) and nBytes <= 2: # unsigned short - * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 1): - * return dataReadUShort(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, bit_count, bit_offset) + * elif signal_data_type in (0, 1, 13, 14) and n_bytes <= 2: # unsigned short + * if (byteorder == 'little' and signal_data_type == 0) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 1): + * return read_unsigned_short(bit_stream, record_format, number_of_records, */ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 74, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -2445,7 +2460,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, goto __pyx_L30_next_or; } else { } - __pyx_t_2 = ((__pyx_v_signalDataType == 0) != 0); + __pyx_t_2 = ((__pyx_v_signal_data_type == 0) != 0); if (!__pyx_t_2) { } else { __pyx_t_3 = __pyx_t_2; @@ -2454,11 +2469,11 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L30_next_or:; /* "dataRead.pyx":75 - * elif signalDataType in (0, 1, 13, 14) and nBytes <= 2: # unsigned short - * if (byteorder == 'little' and signalDataType == 0) or \ - * (byteorder == 'big' and signalDataType == 1): # <<<<<<<<<<<<<< - * return dataReadUShort(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) + * elif signal_data_type in (0, 1, 13, 14) and n_bytes <= 2: # unsigned short + * if (byteorder == 'little' and signal_data_type == 0) or \ + * (byteorder == 'big' and signal_data_type == 1): # <<<<<<<<<<<<<< + * return read_unsigned_short(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, 0) */ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 75, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -2469,68 +2484,68 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_2; goto __pyx_L29_bool_binop_done; } - __pyx_t_2 = ((__pyx_v_signalDataType == 1) != 0); + __pyx_t_2 = ((__pyx_v_signal_data_type == 1) != 0); __pyx_t_3 = __pyx_t_2; __pyx_L29_bool_binop_done:; /* "dataRead.pyx":74 - * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (0, 1, 13, 14) and nBytes <= 2: # unsigned short - * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 1): - * return dataReadUShort(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, bit_count, bit_offset) + * elif signal_data_type in (0, 1, 13, 14) and n_bytes <= 2: # unsigned short + * if (byteorder == 'little' and signal_data_type == 0) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 1): + * return read_unsigned_short(bit_stream, record_format, number_of_records, */ if (__pyx_t_3) { /* "dataRead.pyx":76 - * if (byteorder == 'little' and signalDataType == 0) or \ - * (byteorder == 'big' and signalDataType == 1): - * return dataReadUShort(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) + * if (byteorder == 'little' and signal_data_type == 0) or \ + * (byteorder == 'big' and signal_data_type == 1): + * return read_unsigned_short(bit_stream, record_format, number_of_records, # <<<<<<<<<<<<<< + * record_byte_size, pos_byte_beg, bit_count, bit_offset, 0) * else: # swap bytes */ __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":77 - * (byteorder == 'big' and signalDataType == 1): - * return dataReadUShort(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 1): + * return read_unsigned_short(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, 0) # <<<<<<<<<<<<<< * else: # swap bytes - * return dataReadUShort(bita, RecordFormat, numberOfRecords, + * return read_unsigned_short(bit_stream, record_format, number_of_records, */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadUShort(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 76, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_read_unsigned_short(__pyx_v_bit_stream, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_pos_byte_beg, __pyx_v_bit_count, __pyx_v_bit_offset, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 76, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; /* "dataRead.pyx":74 - * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (0, 1, 13, 14) and nBytes <= 2: # unsigned short - * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 1): - * return dataReadUShort(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, bit_count, bit_offset) + * elif signal_data_type in (0, 1, 13, 14) and n_bytes <= 2: # unsigned short + * if (byteorder == 'little' and signal_data_type == 0) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 1): + * return read_unsigned_short(bit_stream, record_format, number_of_records, */ } /* "dataRead.pyx":79 - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) + * record_byte_size, pos_byte_beg, bit_count, bit_offset, 0) * else: # swap bytes - * return dataReadUShort(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and nBytes <= 2: # signed short + * return read_unsigned_short(bit_stream, record_format, number_of_records, # <<<<<<<<<<<<<< + * record_byte_size, pos_byte_beg, bit_count, bit_offset, 1) + * elif signal_data_type in (2, 3) and n_bytes <= 2: # signed short */ /*else*/ { __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":80 * else: # swap bytes - * return dataReadUShort(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) # <<<<<<<<<<<<<< - * elif signalDataType in (2, 3) and nBytes <= 2: # signed short - * if (byteorder == 'little' and signalDataType == 2) or \ + * return read_unsigned_short(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, 1) # <<<<<<<<<<<<<< + * elif signal_data_type in (2, 3) and n_bytes <= 2: # signed short + * if (byteorder == 'little' and signal_data_type == 2) or \ */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadUShort(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 79, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_read_unsigned_short(__pyx_v_bit_stream, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_pos_byte_beg, __pyx_v_bit_count, __pyx_v_bit_offset, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 79, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; @@ -2538,22 +2553,22 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, } /* "dataRead.pyx":73 - * return dataReadChar(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset) - * elif signalDataType in (0, 1, 13, 14) and nBytes <= 2: # unsigned short # <<<<<<<<<<<<<< - * if (byteorder == 'little' and signalDataType == 0) or \ - * (byteorder == 'big' and signalDataType == 1): + * return read_signed_char(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset) + * elif signal_data_type in (0, 1, 13, 14) and n_bytes <= 2: # unsigned short # <<<<<<<<<<<<<< + * if (byteorder == 'little' and signal_data_type == 0) or \ + * (byteorder == 'big' and signal_data_type == 1): */ } /* "dataRead.pyx":81 - * return dataReadUShort(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and nBytes <= 2: # signed short # <<<<<<<<<<<<<< - * if (byteorder == 'little' and signalDataType == 2) or \ - * (byteorder == 'big' and signalDataType == 3): + * return read_unsigned_short(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, 1) + * elif signal_data_type in (2, 3) and n_bytes <= 2: # signed short # <<<<<<<<<<<<<< + * if (byteorder == 'little' and signal_data_type == 2) or \ + * (byteorder == 'big' and signal_data_type == 3): */ - switch (__pyx_v_signalDataType) { + switch (__pyx_v_signal_data_type) { case 2: case 3: __pyx_t_2 = 1; @@ -2568,17 +2583,17 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_4; goto __pyx_L33_bool_binop_done; } - __pyx_t_4 = ((__pyx_v_nBytes <= 2) != 0); + __pyx_t_4 = ((__pyx_v_n_bytes <= 2) != 0); __pyx_t_3 = __pyx_t_4; __pyx_L33_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":82 - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and nBytes <= 2: # signed short - * if (byteorder == 'little' and signalDataType == 2) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 3): - * return dataReadShort(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, 1) + * elif signal_data_type in (2, 3) and n_bytes <= 2: # signed short + * if (byteorder == 'little' and signal_data_type == 2) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 3): + * return read_signed_short(bit_stream, record_format, number_of_records, */ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 82, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -2588,7 +2603,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, goto __pyx_L37_next_or; } else { } - __pyx_t_4 = ((__pyx_v_signalDataType == 2) != 0); + __pyx_t_4 = ((__pyx_v_signal_data_type == 2) != 0); if (!__pyx_t_4) { } else { __pyx_t_3 = __pyx_t_4; @@ -2597,11 +2612,11 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L37_next_or:; /* "dataRead.pyx":83 - * elif signalDataType in (2, 3) and nBytes <= 2: # signed short - * if (byteorder == 'little' and signalDataType == 2) or \ - * (byteorder == 'big' and signalDataType == 3): # <<<<<<<<<<<<<< - * return dataReadShort(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) + * elif signal_data_type in (2, 3) and n_bytes <= 2: # signed short + * if (byteorder == 'little' and signal_data_type == 2) or \ + * (byteorder == 'big' and signal_data_type == 3): # <<<<<<<<<<<<<< + * return read_signed_short(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, 0) */ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 83, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -2612,68 +2627,68 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_4; goto __pyx_L36_bool_binop_done; } - __pyx_t_4 = ((__pyx_v_signalDataType == 3) != 0); + __pyx_t_4 = ((__pyx_v_signal_data_type == 3) != 0); __pyx_t_3 = __pyx_t_4; __pyx_L36_bool_binop_done:; /* "dataRead.pyx":82 - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and nBytes <= 2: # signed short - * if (byteorder == 'little' and signalDataType == 2) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 3): - * return dataReadShort(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, 1) + * elif signal_data_type in (2, 3) and n_bytes <= 2: # signed short + * if (byteorder == 'little' and signal_data_type == 2) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 3): + * return read_signed_short(bit_stream, record_format, number_of_records, */ if (__pyx_t_3) { /* "dataRead.pyx":84 - * if (byteorder == 'little' and signalDataType == 2) or \ - * (byteorder == 'big' and signalDataType == 3): - * return dataReadShort(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) + * if (byteorder == 'little' and signal_data_type == 2) or \ + * (byteorder == 'big' and signal_data_type == 3): + * return read_signed_short(bit_stream, record_format, number_of_records, # <<<<<<<<<<<<<< + * record_byte_size, pos_byte_beg, bit_count, bit_offset, 0) * else: # swap bytes */ __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":85 - * (byteorder == 'big' and signalDataType == 3): - * return dataReadShort(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 3): + * return read_signed_short(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, 0) # <<<<<<<<<<<<<< * else: # swap bytes - * return dataReadShort(bita, RecordFormat, numberOfRecords, + * return read_signed_short(bit_stream, record_format, number_of_records, */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadShort(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 84, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_read_signed_short(__pyx_v_bit_stream, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_pos_byte_beg, __pyx_v_bit_count, __pyx_v_bit_offset, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 84, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; /* "dataRead.pyx":82 - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and nBytes <= 2: # signed short - * if (byteorder == 'little' and signalDataType == 2) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 3): - * return dataReadShort(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, 1) + * elif signal_data_type in (2, 3) and n_bytes <= 2: # signed short + * if (byteorder == 'little' and signal_data_type == 2) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 3): + * return read_signed_short(bit_stream, record_format, number_of_records, */ } /* "dataRead.pyx":87 - * record_byte_size, posByteBeg, bitCount, bitOffset, 0) + * record_byte_size, pos_byte_beg, bit_count, bit_offset, 0) * else: # swap bytes - * return dataReadShort(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1, 14) and nBytes <= 4: # unsigned int + * return read_signed_short(bit_stream, record_format, number_of_records, # <<<<<<<<<<<<<< + * record_byte_size, pos_byte_beg, bit_count, bit_offset, 1) + * elif signal_data_type in (0, 1, 14) and n_bytes <= 4: # unsigned int */ /*else*/ { __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":88 * else: # swap bytes - * return dataReadShort(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) # <<<<<<<<<<<<<< - * elif signalDataType in (0, 1, 14) and nBytes <= 4: # unsigned int - * if (byteorder == 'little' and signalDataType == 0) or \ + * return read_signed_short(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, 1) # <<<<<<<<<<<<<< + * elif signal_data_type in (0, 1, 14) and n_bytes <= 4: # unsigned int + * if (byteorder == 'little' and signal_data_type == 0) or \ */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadShort(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 87, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_read_signed_short(__pyx_v_bit_stream, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_pos_byte_beg, __pyx_v_bit_count, __pyx_v_bit_offset, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 87, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; @@ -2681,22 +2696,22 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, } /* "dataRead.pyx":81 - * return dataReadUShort(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (2, 3) and nBytes <= 2: # signed short # <<<<<<<<<<<<<< - * if (byteorder == 'little' and signalDataType == 2) or \ - * (byteorder == 'big' and signalDataType == 3): + * return read_unsigned_short(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, 1) + * elif signal_data_type in (2, 3) and n_bytes <= 2: # signed short # <<<<<<<<<<<<<< + * if (byteorder == 'little' and signal_data_type == 2) or \ + * (byteorder == 'big' and signal_data_type == 3): */ } /* "dataRead.pyx":89 - * return dataReadShort(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1, 14) and nBytes <= 4: # unsigned int # <<<<<<<<<<<<<< - * if (byteorder == 'little' and signalDataType == 0) or \ - * (byteorder == 'big' and signalDataType == 1): + * return read_signed_short(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, 1) + * elif signal_data_type in (0, 1, 14) and n_bytes <= 4: # unsigned int # <<<<<<<<<<<<<< + * if (byteorder == 'little' and signal_data_type == 0) or \ + * (byteorder == 'big' and signal_data_type == 1): */ - switch (__pyx_v_signalDataType) { + switch (__pyx_v_signal_data_type) { case 0: case 1: case 14: @@ -2712,17 +2727,17 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_2; goto __pyx_L40_bool_binop_done; } - __pyx_t_2 = ((__pyx_v_nBytes <= 4) != 0); + __pyx_t_2 = ((__pyx_v_n_bytes <= 4) != 0); __pyx_t_3 = __pyx_t_2; __pyx_L40_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":90 - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1, 14) and nBytes <= 4: # unsigned int - * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 1): - * return dataReadUInt(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, 1) + * elif signal_data_type in (0, 1, 14) and n_bytes <= 4: # unsigned int + * if (byteorder == 'little' and signal_data_type == 0) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 1): + * return read_unsigned_int(bit_stream, record_format, number_of_records, */ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 90, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -2732,7 +2747,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, goto __pyx_L44_next_or; } else { } - __pyx_t_2 = ((__pyx_v_signalDataType == 0) != 0); + __pyx_t_2 = ((__pyx_v_signal_data_type == 0) != 0); if (!__pyx_t_2) { } else { __pyx_t_3 = __pyx_t_2; @@ -2741,11 +2756,11 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L44_next_or:; /* "dataRead.pyx":91 - * elif signalDataType in (0, 1, 14) and nBytes <= 4: # unsigned int - * if (byteorder == 'little' and signalDataType == 0) or \ - * (byteorder == 'big' and signalDataType == 1): # <<<<<<<<<<<<<< - * return dataReadUInt(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) + * elif signal_data_type in (0, 1, 14) and n_bytes <= 4: # unsigned int + * if (byteorder == 'little' and signal_data_type == 0) or \ + * (byteorder == 'big' and signal_data_type == 1): # <<<<<<<<<<<<<< + * return read_unsigned_int(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 0) */ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 91, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -2756,68 +2771,68 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_2; goto __pyx_L43_bool_binop_done; } - __pyx_t_2 = ((__pyx_v_signalDataType == 1) != 0); + __pyx_t_2 = ((__pyx_v_signal_data_type == 1) != 0); __pyx_t_3 = __pyx_t_2; __pyx_L43_bool_binop_done:; /* "dataRead.pyx":90 - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1, 14) and nBytes <= 4: # unsigned int - * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 1): - * return dataReadUInt(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, 1) + * elif signal_data_type in (0, 1, 14) and n_bytes <= 4: # unsigned int + * if (byteorder == 'little' and signal_data_type == 0) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 1): + * return read_unsigned_int(bit_stream, record_format, number_of_records, */ if (__pyx_t_3) { /* "dataRead.pyx":92 - * if (byteorder == 'little' and signalDataType == 0) or \ - * (byteorder == 'big' and signalDataType == 1): - * return dataReadUInt(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) + * if (byteorder == 'little' and signal_data_type == 0) or \ + * (byteorder == 'big' and signal_data_type == 1): + * return read_unsigned_int(bit_stream, record_format, number_of_records, # <<<<<<<<<<<<<< + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 0) * else: # swap bytes */ __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":93 - * (byteorder == 'big' and signalDataType == 1): - * return dataReadUInt(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 1): + * return read_unsigned_int(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 0) # <<<<<<<<<<<<<< * else: # swap bytes - * return dataReadUInt(bita, RecordFormat, numberOfRecords, + * return read_unsigned_int(bit_stream, record_format, number_of_records, */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadUInt(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, __pyx_v_nBytes, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 92, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_read_unsigned_int(__pyx_v_bit_stream, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_pos_byte_beg, __pyx_v_bit_count, __pyx_v_bit_offset, __pyx_v_n_bytes, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 92, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; /* "dataRead.pyx":90 - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1, 14) and nBytes <= 4: # unsigned int - * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 1): - * return dataReadUInt(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, 1) + * elif signal_data_type in (0, 1, 14) and n_bytes <= 4: # unsigned int + * if (byteorder == 'little' and signal_data_type == 0) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 1): + * return read_unsigned_int(bit_stream, record_format, number_of_records, */ } /* "dataRead.pyx":95 - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 0) * else: # swap bytes - * return dataReadUInt(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and nBytes <= 4: # signed int + * return read_unsigned_int(bit_stream, record_format, number_of_records, # <<<<<<<<<<<<<< + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) + * elif signal_data_type in (2, 3) and n_bytes <= 4: # signed int */ /*else*/ { __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":96 * else: # swap bytes - * return dataReadUInt(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) # <<<<<<<<<<<<<< - * elif signalDataType in (2, 3) and nBytes <= 4: # signed int - * if (byteorder == 'little' and signalDataType == 2) or \ + * return read_unsigned_int(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) # <<<<<<<<<<<<<< + * elif signal_data_type in (2, 3) and n_bytes <= 4: # signed int + * if (byteorder == 'little' and signal_data_type == 2) or \ */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadUInt(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, __pyx_v_nBytes, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 95, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_read_unsigned_int(__pyx_v_bit_stream, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_pos_byte_beg, __pyx_v_bit_count, __pyx_v_bit_offset, __pyx_v_n_bytes, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 95, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; @@ -2825,22 +2840,22 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, } /* "dataRead.pyx":89 - * return dataReadShort(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, 1) - * elif signalDataType in (0, 1, 14) and nBytes <= 4: # unsigned int # <<<<<<<<<<<<<< - * if (byteorder == 'little' and signalDataType == 0) or \ - * (byteorder == 'big' and signalDataType == 1): + * return read_signed_short(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, 1) + * elif signal_data_type in (0, 1, 14) and n_bytes <= 4: # unsigned int # <<<<<<<<<<<<<< + * if (byteorder == 'little' and signal_data_type == 0) or \ + * (byteorder == 'big' and signal_data_type == 1): */ } /* "dataRead.pyx":97 - * return dataReadUInt(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and nBytes <= 4: # signed int # <<<<<<<<<<<<<< - * if (byteorder == 'little' and signalDataType == 2) or \ - * (byteorder == 'big' and signalDataType == 3): + * return read_unsigned_int(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) + * elif signal_data_type in (2, 3) and n_bytes <= 4: # signed int # <<<<<<<<<<<<<< + * if (byteorder == 'little' and signal_data_type == 2) or \ + * (byteorder == 'big' and signal_data_type == 3): */ - switch (__pyx_v_signalDataType) { + switch (__pyx_v_signal_data_type) { case 2: case 3: __pyx_t_2 = 1; @@ -2855,17 +2870,17 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_4; goto __pyx_L47_bool_binop_done; } - __pyx_t_4 = ((__pyx_v_nBytes <= 4) != 0); + __pyx_t_4 = ((__pyx_v_n_bytes <= 4) != 0); __pyx_t_3 = __pyx_t_4; __pyx_L47_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":98 - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and nBytes <= 4: # signed int - * if (byteorder == 'little' and signalDataType == 2) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 3): - * return dataReadInt(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) + * elif signal_data_type in (2, 3) and n_bytes <= 4: # signed int + * if (byteorder == 'little' and signal_data_type == 2) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 3): + * return read_signed_int(bit_stream, record_format, number_of_records, */ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 98, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -2875,7 +2890,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, goto __pyx_L51_next_or; } else { } - __pyx_t_4 = ((__pyx_v_signalDataType == 2) != 0); + __pyx_t_4 = ((__pyx_v_signal_data_type == 2) != 0); if (!__pyx_t_4) { } else { __pyx_t_3 = __pyx_t_4; @@ -2884,11 +2899,11 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L51_next_or:; /* "dataRead.pyx":99 - * elif signalDataType in (2, 3) and nBytes <= 4: # signed int - * if (byteorder == 'little' and signalDataType == 2) or \ - * (byteorder == 'big' and signalDataType == 3): # <<<<<<<<<<<<<< - * return dataReadInt(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) + * elif signal_data_type in (2, 3) and n_bytes <= 4: # signed int + * if (byteorder == 'little' and signal_data_type == 2) or \ + * (byteorder == 'big' and signal_data_type == 3): # <<<<<<<<<<<<<< + * return read_signed_int(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 0) */ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 99, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -2899,68 +2914,68 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_4; goto __pyx_L50_bool_binop_done; } - __pyx_t_4 = ((__pyx_v_signalDataType == 3) != 0); + __pyx_t_4 = ((__pyx_v_signal_data_type == 3) != 0); __pyx_t_3 = __pyx_t_4; __pyx_L50_bool_binop_done:; /* "dataRead.pyx":98 - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and nBytes <= 4: # signed int - * if (byteorder == 'little' and signalDataType == 2) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 3): - * return dataReadInt(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) + * elif signal_data_type in (2, 3) and n_bytes <= 4: # signed int + * if (byteorder == 'little' and signal_data_type == 2) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 3): + * return read_signed_int(bit_stream, record_format, number_of_records, */ if (__pyx_t_3) { /* "dataRead.pyx":100 - * if (byteorder == 'little' and signalDataType == 2) or \ - * (byteorder == 'big' and signalDataType == 3): - * return dataReadInt(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) + * if (byteorder == 'little' and signal_data_type == 2) or \ + * (byteorder == 'big' and signal_data_type == 3): + * return read_signed_int(bit_stream, record_format, number_of_records, # <<<<<<<<<<<<<< + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 0) * else: # swap bytes */ __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":101 - * (byteorder == 'big' and signalDataType == 3): - * return dataReadInt(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 3): + * return read_signed_int(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 0) # <<<<<<<<<<<<<< * else: # swap bytes - * return dataReadInt(bita, RecordFormat, numberOfRecords, + * return read_signed_int(bit_stream, record_format, number_of_records, */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadInt(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, __pyx_v_nBytes, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 100, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_read_signed_int(__pyx_v_bit_stream, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_pos_byte_beg, __pyx_v_bit_count, __pyx_v_bit_offset, __pyx_v_n_bytes, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 100, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; /* "dataRead.pyx":98 - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and nBytes <= 4: # signed int - * if (byteorder == 'little' and signalDataType == 2) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 3): - * return dataReadInt(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) + * elif signal_data_type in (2, 3) and n_bytes <= 4: # signed int + * if (byteorder == 'little' and signal_data_type == 2) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 3): + * return read_signed_int(bit_stream, record_format, number_of_records, */ } /* "dataRead.pyx":103 - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 0) * else: # swap bytes - * return dataReadInt(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (0, 1) and nBytes <= 8: # unsigned long long + * return read_signed_int(bit_stream, record_format, number_of_records, # <<<<<<<<<<<<<< + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) + * elif signal_data_type in (0, 1) and n_bytes <= 8: # unsigned long long */ /*else*/ { __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":104 * else: # swap bytes - * return dataReadInt(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) # <<<<<<<<<<<<<< - * elif signalDataType in (0, 1) and nBytes <= 8: # unsigned long long - * if (byteorder == 'little' and signalDataType == 0) or \ + * return read_signed_int(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) # <<<<<<<<<<<<<< + * elif signal_data_type in (0, 1) and n_bytes <= 8: # unsigned long long + * if (byteorder == 'little' and signal_data_type == 0) or \ */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadInt(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, __pyx_v_nBytes, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 103, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_read_signed_int(__pyx_v_bit_stream, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_pos_byte_beg, __pyx_v_bit_count, __pyx_v_bit_offset, __pyx_v_n_bytes, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 103, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; @@ -2968,22 +2983,22 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, } /* "dataRead.pyx":97 - * return dataReadUInt(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and nBytes <= 4: # signed int # <<<<<<<<<<<<<< - * if (byteorder == 'little' and signalDataType == 2) or \ - * (byteorder == 'big' and signalDataType == 3): + * return read_unsigned_int(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) + * elif signal_data_type in (2, 3) and n_bytes <= 4: # signed int # <<<<<<<<<<<<<< + * if (byteorder == 'little' and signal_data_type == 2) or \ + * (byteorder == 'big' and signal_data_type == 3): */ } /* "dataRead.pyx":105 - * return dataReadInt(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (0, 1) and nBytes <= 8: # unsigned long long # <<<<<<<<<<<<<< - * if (byteorder == 'little' and signalDataType == 0) or \ - * (byteorder == 'big' and signalDataType == 1): + * return read_signed_int(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) + * elif signal_data_type in (0, 1) and n_bytes <= 8: # unsigned long long # <<<<<<<<<<<<<< + * if (byteorder == 'little' and signal_data_type == 0) or \ + * (byteorder == 'big' and signal_data_type == 1): */ - switch (__pyx_v_signalDataType) { + switch (__pyx_v_signal_data_type) { case 0: case 1: __pyx_t_4 = 1; @@ -2998,17 +3013,17 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_2; goto __pyx_L54_bool_binop_done; } - __pyx_t_2 = ((__pyx_v_nBytes <= 8) != 0); + __pyx_t_2 = ((__pyx_v_n_bytes <= 8) != 0); __pyx_t_3 = __pyx_t_2; __pyx_L54_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":106 - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (0, 1) and nBytes <= 8: # unsigned long long - * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 1): - * return dataReadULongLong(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) + * elif signal_data_type in (0, 1) and n_bytes <= 8: # unsigned long long + * if (byteorder == 'little' and signal_data_type == 0) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 1): + * return read_unsigned_longlong(bit_stream, record_format, number_of_records, */ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 106, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -3018,7 +3033,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, goto __pyx_L58_next_or; } else { } - __pyx_t_2 = ((__pyx_v_signalDataType == 0) != 0); + __pyx_t_2 = ((__pyx_v_signal_data_type == 0) != 0); if (!__pyx_t_2) { } else { __pyx_t_3 = __pyx_t_2; @@ -3027,11 +3042,11 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L58_next_or:; /* "dataRead.pyx":107 - * elif signalDataType in (0, 1) and nBytes <= 8: # unsigned long long - * if (byteorder == 'little' and signalDataType == 0) or \ - * (byteorder == 'big' and signalDataType == 1): # <<<<<<<<<<<<<< - * return dataReadULongLong(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) + * elif signal_data_type in (0, 1) and n_bytes <= 8: # unsigned long long + * if (byteorder == 'little' and signal_data_type == 0) or \ + * (byteorder == 'big' and signal_data_type == 1): # <<<<<<<<<<<<<< + * return read_unsigned_longlong(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 0) */ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 107, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -3042,68 +3057,68 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_2; goto __pyx_L57_bool_binop_done; } - __pyx_t_2 = ((__pyx_v_signalDataType == 1) != 0); + __pyx_t_2 = ((__pyx_v_signal_data_type == 1) != 0); __pyx_t_3 = __pyx_t_2; __pyx_L57_bool_binop_done:; /* "dataRead.pyx":106 - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (0, 1) and nBytes <= 8: # unsigned long long - * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 1): - * return dataReadULongLong(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) + * elif signal_data_type in (0, 1) and n_bytes <= 8: # unsigned long long + * if (byteorder == 'little' and signal_data_type == 0) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 1): + * return read_unsigned_longlong(bit_stream, record_format, number_of_records, */ if (__pyx_t_3) { /* "dataRead.pyx":108 - * if (byteorder == 'little' and signalDataType == 0) or \ - * (byteorder == 'big' and signalDataType == 1): - * return dataReadULongLong(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) + * if (byteorder == 'little' and signal_data_type == 0) or \ + * (byteorder == 'big' and signal_data_type == 1): + * return read_unsigned_longlong(bit_stream, record_format, number_of_records, # <<<<<<<<<<<<<< + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 0) * else: # swap bytes */ __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":109 - * (byteorder == 'big' and signalDataType == 1): - * return dataReadULongLong(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 1): + * return read_unsigned_longlong(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 0) # <<<<<<<<<<<<<< * else: # swap bytes - * return dataReadULongLong(bita, RecordFormat, numberOfRecords, + * return read_unsigned_longlong(bit_stream, record_format, number_of_records, */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadULongLong(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, __pyx_v_nBytes, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 108, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_read_unsigned_longlong(__pyx_v_bit_stream, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_pos_byte_beg, __pyx_v_bit_count, __pyx_v_bit_offset, __pyx_v_n_bytes, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 108, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; /* "dataRead.pyx":106 - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (0, 1) and nBytes <= 8: # unsigned long long - * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 1): - * return dataReadULongLong(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) + * elif signal_data_type in (0, 1) and n_bytes <= 8: # unsigned long long + * if (byteorder == 'little' and signal_data_type == 0) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 1): + * return read_unsigned_longlong(bit_stream, record_format, number_of_records, */ } /* "dataRead.pyx":111 - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 0) * else: # swap bytes - * return dataReadULongLong(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and nBytes <= 8: # signed long long + * return read_unsigned_longlong(bit_stream, record_format, number_of_records, # <<<<<<<<<<<<<< + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) + * elif signal_data_type in (2, 3) and n_bytes <= 8: # signed long long */ /*else*/ { __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":112 * else: # swap bytes - * return dataReadULongLong(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) # <<<<<<<<<<<<<< - * elif signalDataType in (2, 3) and nBytes <= 8: # signed long long - * if (byteorder == 'little' and signalDataType == 0) or \ + * return read_unsigned_longlong(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) # <<<<<<<<<<<<<< + * elif signal_data_type in (2, 3) and n_bytes <= 8: # signed long long + * if (byteorder == 'little' and signal_data_type == 0) or \ */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadULongLong(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, __pyx_v_nBytes, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 111, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_read_unsigned_longlong(__pyx_v_bit_stream, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_pos_byte_beg, __pyx_v_bit_count, __pyx_v_bit_offset, __pyx_v_n_bytes, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 111, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; @@ -3111,22 +3126,22 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, } /* "dataRead.pyx":105 - * return dataReadInt(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (0, 1) and nBytes <= 8: # unsigned long long # <<<<<<<<<<<<<< - * if (byteorder == 'little' and signalDataType == 0) or \ - * (byteorder == 'big' and signalDataType == 1): + * return read_signed_int(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) + * elif signal_data_type in (0, 1) and n_bytes <= 8: # unsigned long long # <<<<<<<<<<<<<< + * if (byteorder == 'little' and signal_data_type == 0) or \ + * (byteorder == 'big' and signal_data_type == 1): */ } /* "dataRead.pyx":113 - * return dataReadULongLong(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and nBytes <= 8: # signed long long # <<<<<<<<<<<<<< - * if (byteorder == 'little' and signalDataType == 0) or \ - * (byteorder == 'big' and signalDataType == 1): + * return read_unsigned_longlong(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) + * elif signal_data_type in (2, 3) and n_bytes <= 8: # signed long long # <<<<<<<<<<<<<< + * if (byteorder == 'little' and signal_data_type == 0) or \ + * (byteorder == 'big' and signal_data_type == 1): */ - switch (__pyx_v_signalDataType) { + switch (__pyx_v_signal_data_type) { case 2: case 3: __pyx_t_2 = 1; @@ -3141,17 +3156,17 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_4; goto __pyx_L61_bool_binop_done; } - __pyx_t_4 = ((__pyx_v_nBytes <= 8) != 0); + __pyx_t_4 = ((__pyx_v_n_bytes <= 8) != 0); __pyx_t_3 = __pyx_t_4; __pyx_L61_bool_binop_done:; if (__pyx_t_3) { /* "dataRead.pyx":114 - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and nBytes <= 8: # signed long long - * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 1): - * return dataReadLongLong(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) + * elif signal_data_type in (2, 3) and n_bytes <= 8: # signed long long + * if (byteorder == 'little' and signal_data_type == 0) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 1): + * return read_signed_longlong(bit_stream, record_format, number_of_records, */ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 114, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -3161,7 +3176,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, goto __pyx_L65_next_or; } else { } - __pyx_t_4 = ((__pyx_v_signalDataType == 0) != 0); + __pyx_t_4 = ((__pyx_v_signal_data_type == 0) != 0); if (!__pyx_t_4) { } else { __pyx_t_3 = __pyx_t_4; @@ -3170,11 +3185,11 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L65_next_or:; /* "dataRead.pyx":115 - * elif signalDataType in (2, 3) and nBytes <= 8: # signed long long - * if (byteorder == 'little' and signalDataType == 0) or \ - * (byteorder == 'big' and signalDataType == 1): # <<<<<<<<<<<<<< - * return dataReadLongLong(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) + * elif signal_data_type in (2, 3) and n_bytes <= 8: # signed long long + * if (byteorder == 'little' and signal_data_type == 0) or \ + * (byteorder == 'big' and signal_data_type == 1): # <<<<<<<<<<<<<< + * return read_signed_longlong(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 0) */ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 115, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -3185,55 +3200,55 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_4; goto __pyx_L64_bool_binop_done; } - __pyx_t_4 = ((__pyx_v_signalDataType == 1) != 0); + __pyx_t_4 = ((__pyx_v_signal_data_type == 1) != 0); __pyx_t_3 = __pyx_t_4; __pyx_L64_bool_binop_done:; /* "dataRead.pyx":114 - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and nBytes <= 8: # signed long long - * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 1): - * return dataReadLongLong(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) + * elif signal_data_type in (2, 3) and n_bytes <= 8: # signed long long + * if (byteorder == 'little' and signal_data_type == 0) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 1): + * return read_signed_longlong(bit_stream, record_format, number_of_records, */ if (__pyx_t_3) { /* "dataRead.pyx":116 - * if (byteorder == 'little' and signalDataType == 0) or \ - * (byteorder == 'big' and signalDataType == 1): - * return dataReadLongLong(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) + * if (byteorder == 'little' and signal_data_type == 0) or \ + * (byteorder == 'big' and signal_data_type == 1): + * return read_signed_longlong(bit_stream, record_format, number_of_records, # <<<<<<<<<<<<<< + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 0) * else: # swap bytes */ __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":117 - * (byteorder == 'big' and signalDataType == 1): - * return dataReadLongLong(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 1): + * return read_signed_longlong(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 0) # <<<<<<<<<<<<<< * else: # swap bytes - * return dataReadLongLong(bita, RecordFormat, numberOfRecords, + * return read_signed_longlong(bit_stream, record_format, number_of_records, */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadLongLong(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, __pyx_v_nBytes, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 116, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_read_signed_longlong(__pyx_v_bit_stream, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_pos_byte_beg, __pyx_v_bit_count, __pyx_v_bit_offset, __pyx_v_n_bytes, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 116, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; /* "dataRead.pyx":114 - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and nBytes <= 8: # signed long long - * if (byteorder == 'little' and signalDataType == 0) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType == 1): - * return dataReadLongLong(bita, RecordFormat, numberOfRecords, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) + * elif signal_data_type in (2, 3) and n_bytes <= 8: # signed long long + * if (byteorder == 'little' and signal_data_type == 0) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type == 1): + * return read_signed_longlong(bit_stream, record_format, number_of_records, */ } /* "dataRead.pyx":119 - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 0) + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 0) * else: # swap bytes - * return dataReadLongLong(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) + * return read_signed_longlong(bit_stream, record_format, number_of_records, # <<<<<<<<<<<<<< + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) * else: */ /*else*/ { @@ -3241,12 +3256,12 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":120 * else: # swap bytes - * return dataReadLongLong(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) # <<<<<<<<<<<<<< + * return read_signed_longlong(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) # <<<<<<<<<<<<<< * else: - * return dataReadByte(bita, RecordFormat, numberOfRecords, + * return read_byte(bit_stream, record_format, number_of_records, */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadLongLong(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_bitCount, __pyx_v_bitOffset, __pyx_v_nBytes, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 119, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_read_signed_longlong(__pyx_v_bit_stream, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_pos_byte_beg, __pyx_v_bit_count, __pyx_v_bit_offset, __pyx_v_n_bytes, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 119, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; @@ -3254,19 +3269,19 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, } /* "dataRead.pyx":113 - * return dataReadULongLong(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) - * elif signalDataType in (2, 3) and nBytes <= 8: # signed long long # <<<<<<<<<<<<<< - * if (byteorder == 'little' and signalDataType == 0) or \ - * (byteorder == 'big' and signalDataType == 1): + * return read_unsigned_longlong(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) + * elif signal_data_type in (2, 3) and n_bytes <= 8: # signed long long # <<<<<<<<<<<<<< + * if (byteorder == 'little' and signal_data_type == 0) or \ + * (byteorder == 'big' and signal_data_type == 1): */ } /* "dataRead.pyx":122 - * record_byte_size, posByteBeg, bitCount, bitOffset, nBytes, 1) + * record_byte_size, pos_byte_beg, bit_count, bit_offset, n_bytes, 1) * else: - * return dataReadByte(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) + * return read_byte(bit_stream, record_format, number_of_records, # <<<<<<<<<<<<<< + * record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset) * else: # array */ /*else*/ { @@ -3274,12 +3289,12 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":123 * else: - * return dataReadByte(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) # <<<<<<<<<<<<<< + * return read_byte(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset) # <<<<<<<<<<<<<< * else: # array - * if (byteorder == 'little' and signalDataType in (0, 2, 4)) or \ + * if (byteorder == 'little' and signal_data_type in (0, 2, 4)) or \ */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadByte(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_nBytes, __pyx_v_bitCount, __pyx_v_bitOffset); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 122, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_read_byte(__pyx_v_bit_stream, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_pos_byte_beg, __pyx_v_n_bytes, __pyx_v_bit_count, __pyx_v_bit_offset); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 122, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; @@ -3288,19 +3303,19 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":47 * """ - * cdef char* bita = PyBytes_AsString(tmp) + * cdef char* bit_stream = PyBytes_AsString(tmp) * if not array: # <<<<<<<<<<<<<< - * if 'V' in RecordFormat or 'S' in RecordFormat or RecordFormat is None: - * return dataReadByte(bita, RecordFormat, numberOfRecords, + * if 'V' in record_format or 'S' in record_format or record_format is None: + * return read_byte(bit_stream, record_format, number_of_records, */ } /* "dataRead.pyx":125 - * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) + * record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset) * else: # array - * if (byteorder == 'little' and signalDataType in (0, 2, 4)) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType in (1, 3, 5)): - * return dataReadArray(bita, RecordFormat, numberOfRecords, + * if (byteorder == 'little' and signal_data_type in (0, 2, 4)) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type in (1, 3, 5)): + * return read_array(bit_stream, record_format, number_of_records, */ /*else*/ { __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 125, __pyx_L1_error) @@ -3311,7 +3326,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, goto __pyx_L70_next_or; } else { } - switch (__pyx_v_signalDataType) { + switch (__pyx_v_signal_data_type) { case 0: case 2: case 4: @@ -3331,10 +3346,10 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":126 * else: # array - * if (byteorder == 'little' and signalDataType in (0, 2, 4)) or \ - * (byteorder == 'big' and signalDataType in (1, 3, 5)): # <<<<<<<<<<<<<< - * return dataReadArray(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset, 0) + * if (byteorder == 'little' and signal_data_type in (0, 2, 4)) or \ + * (byteorder == 'big' and signal_data_type in (1, 3, 5)): # <<<<<<<<<<<<<< + * return read_array(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset, 0) */ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_byteorder); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 126, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); @@ -3345,7 +3360,7 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_t_3 = __pyx_t_2; goto __pyx_L69_bool_binop_done; } - switch (__pyx_v_signalDataType) { + switch (__pyx_v_signal_data_type) { case 1: case 3: case 5: @@ -3360,50 +3375,50 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, __pyx_L69_bool_binop_done:; /* "dataRead.pyx":125 - * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) + * record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset) * else: # array - * if (byteorder == 'little' and signalDataType in (0, 2, 4)) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType in (1, 3, 5)): - * return dataReadArray(bita, RecordFormat, numberOfRecords, + * if (byteorder == 'little' and signal_data_type in (0, 2, 4)) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type in (1, 3, 5)): + * return read_array(bit_stream, record_format, number_of_records, */ if (__pyx_t_3) { /* "dataRead.pyx":127 - * if (byteorder == 'little' and signalDataType in (0, 2, 4)) or \ - * (byteorder == 'big' and signalDataType in (1, 3, 5)): - * return dataReadArray(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset, 0) + * if (byteorder == 'little' and signal_data_type in (0, 2, 4)) or \ + * (byteorder == 'big' and signal_data_type in (1, 3, 5)): + * return read_array(bit_stream, record_format, number_of_records, # <<<<<<<<<<<<<< + * record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset, 0) * else: # swap bytes */ __Pyx_XDECREF(__pyx_r); /* "dataRead.pyx":128 - * (byteorder == 'big' and signalDataType in (1, 3, 5)): - * return dataReadArray(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset, 0) # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type in (1, 3, 5)): + * return read_array(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset, 0) # <<<<<<<<<<<<<< * else: # swap bytes - * return dataReadArray(bita, RecordFormat, numberOfRecords, + * return read_array(bit_stream, record_format, number_of_records, */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadArray(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_nBytes, __pyx_v_bitCount, __pyx_v_bitOffset, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 127, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_read_array(__pyx_v_bit_stream, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_pos_byte_beg, __pyx_v_n_bytes, __pyx_v_bit_count, __pyx_v_bit_offset, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 127, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; goto __pyx_L0; /* "dataRead.pyx":125 - * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset) + * record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset) * else: # array - * if (byteorder == 'little' and signalDataType in (0, 2, 4)) or \ # <<<<<<<<<<<<<< - * (byteorder == 'big' and signalDataType in (1, 3, 5)): - * return dataReadArray(bita, RecordFormat, numberOfRecords, + * if (byteorder == 'little' and signal_data_type in (0, 2, 4)) or \ # <<<<<<<<<<<<<< + * (byteorder == 'big' and signal_data_type in (1, 3, 5)): + * return read_array(bit_stream, record_format, number_of_records, */ } /* "dataRead.pyx":130 - * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset, 0) + * record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset, 0) * else: # swap bytes - * return dataReadArray(bita, RecordFormat, numberOfRecords, # <<<<<<<<<<<<<< - * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset, 1) + * return read_array(bit_stream, record_format, number_of_records, # <<<<<<<<<<<<<< + * record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset, 1) * */ /*else*/ { @@ -3411,12 +3426,12 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":131 * else: # swap bytes - * return dataReadArray(bita, RecordFormat, numberOfRecords, - * record_byte_size, posByteBeg, nBytes, bitCount, bitOffset, 1) # <<<<<<<<<<<<<< + * return read_array(bit_stream, record_format, number_of_records, + * record_byte_size, pos_byte_beg, n_bytes, bit_count, bit_offset, 1) # <<<<<<<<<<<<<< * * */ - __pyx_t_5 = __pyx_f_8dataRead_dataReadArray(__pyx_v_bita, __pyx_v_RecordFormat, __pyx_v_numberOfRecords, __pyx_v_record_byte_size, __pyx_v_posByteBeg, __pyx_v_nBytes, __pyx_v_bitCount, __pyx_v_bitOffset, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 130, __pyx_L1_error) + __pyx_t_5 = __pyx_f_8dataRead_read_array(__pyx_v_bit_stream, __pyx_v_record_format, __pyx_v_number_of_records, __pyx_v_record_byte_size, __pyx_v_pos_byte_beg, __pyx_v_n_bytes, __pyx_v_bit_count, __pyx_v_bit_offset, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 130, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __pyx_r = __pyx_t_5; __pyx_t_5 = 0; @@ -3427,15 +3442,15 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":11 * #@cython.boundscheck(False) * #@cython.wraparound(False) - * def dataRead(bytes tmp, unsigned short bitCount, # <<<<<<<<<<<<<< - * unsigned short signalDataType, str RecordFormat, unsigned long long numberOfRecords, - * unsigned long record_byte_size, unsigned char bitOffset, + * def data_read(bytes tmp, unsigned short bit_count, # <<<<<<<<<<<<<< + * unsigned short signal_data_type, str record_format, unsigned long long number_of_records, + * unsigned long record_byte_size, unsigned char bit_offset, */ /* function exit code */ __pyx_L1_error:; __Pyx_XDECREF(__pyx_t_5); - __Pyx_AddTraceback("dataRead.dataRead", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("dataRead.data_read", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; __Pyx_XGIVEREF(__pyx_r); @@ -3446,15 +3461,15 @@ static PyObject *__pyx_pf_8dataRead_dataRead(CYTHON_UNUSED PyObject *__pyx_self, /* "dataRead.pyx":134 * * - * cdef inline dataReadFloat(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, unsigned char swap): - * cdef np.ndarray[np.float32_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array + * cdef inline read_float(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, unsigned char swap): + * cdef np.ndarray[np.float32_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array */ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadFloat(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned char __pyx_v_swap) { +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_float(char const *__pyx_v_bit_stream, PyObject *__pyx_v_record_format, unsigned PY_LONG_LONG __pyx_v_number_of_records, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_pos_byte_beg, unsigned char __pyx_v_swap) { PyArrayObject *__pyx_v_buf = 0; unsigned PY_LONG_LONG __pyx_v_i; - float __pyx_v_tempfloat; + float __pyx_v_temp_float; __Pyx_LocalBuf_ND __pyx_pybuffernd_buf; __Pyx_Buffer __pyx_pybuffer_buf; PyObject *__pyx_r = NULL; @@ -3470,25 +3485,25 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadFloat(char const *__pyx unsigned PY_LONG_LONG __pyx_t_9; int __pyx_t_10; int __pyx_t_11; - __Pyx_RefNannySetupContext("dataReadFloat", 0); + __Pyx_RefNannySetupContext("read_float", 0); __pyx_pybuffer_buf.pybuffer.buf = NULL; __pyx_pybuffer_buf.refcount = 0; __pyx_pybuffernd_buf.data = NULL; __pyx_pybuffernd_buf.rcbuffer = &__pyx_pybuffer_buf; /* "dataRead.pyx":136 - * cdef inline dataReadFloat(const char* bita, str RecordFormat, unsigned long long numberOfRecords, - * unsigned long record_byte_size, unsigned long posByteBeg, unsigned char swap): - * cdef np.ndarray[np.float32_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array # <<<<<<<<<<<<<< + * cdef inline read_float(const char* bit_stream, str record_format, unsigned long long number_of_records, + * unsigned long record_byte_size, unsigned long pos_byte_beg, unsigned char swap): + * cdef np.ndarray[np.float32_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array # <<<<<<<<<<<<<< * cdef unsigned long long i - * cdef float tempfloat = 0 + * cdef float temp_float = 0 */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 136, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 136, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_numberOfRecords); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 136, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_number_of_records); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 136, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 136, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); @@ -3497,7 +3512,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadFloat(char const *__pyx __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 136, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 136, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_record_format) < 0) __PYX_ERR(0, 136, __pyx_L1_error) __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 136, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; @@ -3518,39 +3533,39 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadFloat(char const *__pyx __pyx_t_4 = 0; /* "dataRead.pyx":138 - * cdef np.ndarray[np.float32_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array + * cdef np.ndarray[np.float32_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array * cdef unsigned long long i - * cdef float tempfloat = 0 # <<<<<<<<<<<<<< + * cdef float temp_float = 0 # <<<<<<<<<<<<<< * cdef char temp[4] - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ - __pyx_v_tempfloat = 0.0; + __pyx_v_temp_float = 0.0; /* "dataRead.pyx":140 - * cdef float tempfloat = 0 + * cdef float temp_float = 0 * cdef char temp[4] - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&tempfloat, &bita[posByteBeg + record_byte_size * i], 4) - * buf[i] = tempfloat + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp_float, &bit_stream[pos_byte_beg + record_byte_size * i], 4) + * buf[i] = temp_float */ - __pyx_t_6 = __pyx_v_numberOfRecords; + __pyx_t_6 = __pyx_v_number_of_records; __pyx_t_7 = __pyx_t_6; for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) { __pyx_v_i = __pyx_t_8; /* "dataRead.pyx":141 * cdef char temp[4] - * for i in range(numberOfRecords): - * memcpy(&tempfloat, &bita[posByteBeg + record_byte_size * i], 4) # <<<<<<<<<<<<<< - * buf[i] = tempfloat + * for i in range(number_of_records): + * memcpy(&temp_float, &bit_stream[pos_byte_beg + record_byte_size * i], 4) # <<<<<<<<<<<<<< + * buf[i] = temp_float * if swap == 0: */ - (void)(memcpy((&__pyx_v_tempfloat), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), 4)); + (void)(memcpy((&__pyx_v_temp_float), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), 4)); /* "dataRead.pyx":142 - * for i in range(numberOfRecords): - * memcpy(&tempfloat, &bita[posByteBeg + record_byte_size * i], 4) - * buf[i] = tempfloat # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp_float, &bit_stream[pos_byte_beg + record_byte_size * i], 4) + * buf[i] = temp_float # <<<<<<<<<<<<<< * if swap == 0: * return buf */ @@ -3561,12 +3576,12 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadFloat(char const *__pyx __Pyx_RaiseBufferIndexError(__pyx_t_10); __PYX_ERR(0, 142, __pyx_L1_error) } - *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float32_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_9, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_tempfloat; + *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float32_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_9, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp_float; } /* "dataRead.pyx":143 - * memcpy(&tempfloat, &bita[posByteBeg + record_byte_size * i], 4) - * buf[i] = tempfloat + * memcpy(&temp_float, &bit_stream[pos_byte_beg + record_byte_size * i], 4) + * buf[i] = temp_float * if swap == 0: # <<<<<<<<<<<<<< * return buf * else: @@ -3575,7 +3590,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadFloat(char const *__pyx if (__pyx_t_11) { /* "dataRead.pyx":144 - * buf[i] = tempfloat + * buf[i] = temp_float * if swap == 0: * return buf # <<<<<<<<<<<<<< * else: @@ -3587,8 +3602,8 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadFloat(char const *__pyx goto __pyx_L0; /* "dataRead.pyx":143 - * memcpy(&tempfloat, &bita[posByteBeg + record_byte_size * i], 4) - * buf[i] = tempfloat + * memcpy(&temp_float, &bit_stream[pos_byte_beg + record_byte_size * i], 4) + * buf[i] = temp_float * if swap == 0: # <<<<<<<<<<<<<< * return buf * else: @@ -3600,7 +3615,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadFloat(char const *__pyx * else: * return buf.byteswap() # <<<<<<<<<<<<<< * - * cdef inline dataReadDouble(const char* bita, str RecordFormat, unsigned long long numberOfRecords, + * cdef inline read_double(const char* bit_stream, str record_format, unsigned long long number_of_records, */ /*else*/ { __Pyx_XDECREF(__pyx_r); @@ -3632,9 +3647,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadFloat(char const *__pyx /* "dataRead.pyx":134 * * - * cdef inline dataReadFloat(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, unsigned char swap): - * cdef np.ndarray[np.float32_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array + * cdef inline read_float(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, unsigned char swap): + * cdef np.ndarray[np.float32_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array */ /* function exit code */ @@ -3649,7 +3664,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadFloat(char const *__pyx __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_buf.rcbuffer->pybuffer); __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} - __Pyx_AddTraceback("dataRead.dataReadFloat", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("dataRead.read_float", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; goto __pyx_L2; __pyx_L0:; @@ -3664,15 +3679,15 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadFloat(char const *__pyx /* "dataRead.pyx":148 * return buf.byteswap() * - * cdef inline dataReadDouble(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, unsigned char swap): - * cdef np.ndarray[np.float64_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array + * cdef inline read_double(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, unsigned char swap): + * cdef np.ndarray[np.float64_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array */ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadDouble(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned char __pyx_v_swap) { +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_double(char const *__pyx_v_bit_stream, PyObject *__pyx_v_record_format, unsigned PY_LONG_LONG __pyx_v_number_of_records, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_pos_byte_beg, unsigned char __pyx_v_swap) { PyArrayObject *__pyx_v_buf = 0; unsigned PY_LONG_LONG __pyx_v_i; - double __pyx_v_tempDouble; + double __pyx_v_temp_double; __Pyx_LocalBuf_ND __pyx_pybuffernd_buf; __Pyx_Buffer __pyx_pybuffer_buf; PyObject *__pyx_r = NULL; @@ -3688,25 +3703,25 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadDouble(char const *__py unsigned PY_LONG_LONG __pyx_t_9; int __pyx_t_10; int __pyx_t_11; - __Pyx_RefNannySetupContext("dataReadDouble", 0); + __Pyx_RefNannySetupContext("read_double", 0); __pyx_pybuffer_buf.pybuffer.buf = NULL; __pyx_pybuffer_buf.refcount = 0; __pyx_pybuffernd_buf.data = NULL; __pyx_pybuffernd_buf.rcbuffer = &__pyx_pybuffer_buf; /* "dataRead.pyx":150 - * cdef inline dataReadDouble(const char* bita, str RecordFormat, unsigned long long numberOfRecords, - * unsigned long record_byte_size, unsigned long posByteBeg, unsigned char swap): - * cdef np.ndarray[np.float64_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array # <<<<<<<<<<<<<< + * cdef inline read_double(const char* bit_stream, str record_format, unsigned long long number_of_records, + * unsigned long record_byte_size, unsigned long pos_byte_beg, unsigned char swap): + * cdef np.ndarray[np.float64_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array # <<<<<<<<<<<<<< * cdef unsigned long long i - * cdef double tempDouble = 0 + * cdef double temp_double = 0 */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 150, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 150, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_numberOfRecords); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 150, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_number_of_records); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 150, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 150, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); @@ -3715,7 +3730,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadDouble(char const *__py __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 150, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 150, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_record_format) < 0) __PYX_ERR(0, 150, __pyx_L1_error) __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 150, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; @@ -3736,39 +3751,39 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadDouble(char const *__py __pyx_t_4 = 0; /* "dataRead.pyx":152 - * cdef np.ndarray[np.float64_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array + * cdef np.ndarray[np.float64_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array * cdef unsigned long long i - * cdef double tempDouble = 0 # <<<<<<<<<<<<<< + * cdef double temp_double = 0 # <<<<<<<<<<<<<< * cdef char temp[8] - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ - __pyx_v_tempDouble = 0.0; + __pyx_v_temp_double = 0.0; /* "dataRead.pyx":154 - * cdef double tempDouble = 0 + * cdef double temp_double = 0 * cdef char temp[8] - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&tempDouble, &bita[posByteBeg + record_byte_size * i], 8) - * buf[i] = tempDouble + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp_double, &bit_stream[pos_byte_beg + record_byte_size * i], 8) + * buf[i] = temp_double */ - __pyx_t_6 = __pyx_v_numberOfRecords; + __pyx_t_6 = __pyx_v_number_of_records; __pyx_t_7 = __pyx_t_6; for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) { __pyx_v_i = __pyx_t_8; /* "dataRead.pyx":155 * cdef char temp[8] - * for i in range(numberOfRecords): - * memcpy(&tempDouble, &bita[posByteBeg + record_byte_size * i], 8) # <<<<<<<<<<<<<< - * buf[i] = tempDouble + * for i in range(number_of_records): + * memcpy(&temp_double, &bit_stream[pos_byte_beg + record_byte_size * i], 8) # <<<<<<<<<<<<<< + * buf[i] = temp_double * if swap == 0: */ - (void)(memcpy((&__pyx_v_tempDouble), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), 8)); + (void)(memcpy((&__pyx_v_temp_double), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), 8)); /* "dataRead.pyx":156 - * for i in range(numberOfRecords): - * memcpy(&tempDouble, &bita[posByteBeg + record_byte_size * i], 8) - * buf[i] = tempDouble # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp_double, &bit_stream[pos_byte_beg + record_byte_size * i], 8) + * buf[i] = temp_double # <<<<<<<<<<<<<< * if swap == 0: * return buf */ @@ -3779,12 +3794,12 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadDouble(char const *__py __Pyx_RaiseBufferIndexError(__pyx_t_10); __PYX_ERR(0, 156, __pyx_L1_error) } - *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_9, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_tempDouble; + *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float64_t *, __pyx_pybuffernd_buf.rcbuffer->pybuffer.buf, __pyx_t_9, __pyx_pybuffernd_buf.diminfo[0].strides) = __pyx_v_temp_double; } /* "dataRead.pyx":157 - * memcpy(&tempDouble, &bita[posByteBeg + record_byte_size * i], 8) - * buf[i] = tempDouble + * memcpy(&temp_double, &bit_stream[pos_byte_beg + record_byte_size * i], 8) + * buf[i] = temp_double * if swap == 0: # <<<<<<<<<<<<<< * return buf * else: @@ -3793,7 +3808,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadDouble(char const *__py if (__pyx_t_11) { /* "dataRead.pyx":158 - * buf[i] = tempDouble + * buf[i] = temp_double * if swap == 0: * return buf # <<<<<<<<<<<<<< * else: @@ -3805,8 +3820,8 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadDouble(char const *__py goto __pyx_L0; /* "dataRead.pyx":157 - * memcpy(&tempDouble, &bita[posByteBeg + record_byte_size * i], 8) - * buf[i] = tempDouble + * memcpy(&temp_double, &bit_stream[pos_byte_beg + record_byte_size * i], 8) + * buf[i] = temp_double * if swap == 0: # <<<<<<<<<<<<<< * return buf * else: @@ -3818,7 +3833,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadDouble(char const *__py * else: * return buf.byteswap() # <<<<<<<<<<<<<< * - * cdef inline dataReadUChar(const char* bita, str RecordFormat, unsigned long long numberOfRecords, + * cdef inline read_unsigned_char(const char* bit_stream, str record_format, unsigned long long number_of_records, */ /*else*/ { __Pyx_XDECREF(__pyx_r); @@ -3850,9 +3865,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadDouble(char const *__py /* "dataRead.pyx":148 * return buf.byteswap() * - * cdef inline dataReadDouble(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, unsigned char swap): - * cdef np.ndarray[np.float64_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array + * cdef inline read_double(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, unsigned char swap): + * cdef np.ndarray[np.float64_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array */ /* function exit code */ @@ -3867,7 +3882,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadDouble(char const *__py __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_buf.rcbuffer->pybuffer); __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} - __Pyx_AddTraceback("dataRead.dataReadDouble", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("dataRead.read_double", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; goto __pyx_L2; __pyx_L0:; @@ -3882,12 +3897,12 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadDouble(char const *__py /* "dataRead.pyx":162 * return buf.byteswap() * - * cdef inline dataReadUChar(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset): + * cdef inline read_unsigned_char(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset): */ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUChar(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_bitCount, unsigned char __pyx_v_bitOffset) { +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_unsigned_char(char const *__pyx_v_bit_stream, PyObject *__pyx_v_record_format, unsigned PY_LONG_LONG __pyx_v_number_of_records, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_pos_byte_beg, unsigned long __pyx_v_bit_count, unsigned char __pyx_v_bit_offset) { PyArrayObject *__pyx_v_buf = 0; unsigned PY_LONG_LONG __pyx_v_i; unsigned char __pyx_v_mask; @@ -3908,25 +3923,25 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUChar(char const *__pyx unsigned PY_LONG_LONG __pyx_t_10; int __pyx_t_11; unsigned PY_LONG_LONG __pyx_t_12; - __Pyx_RefNannySetupContext("dataReadUChar", 0); + __Pyx_RefNannySetupContext("read_unsigned_char", 0); __pyx_pybuffer_buf.pybuffer.buf = NULL; __pyx_pybuffer_buf.refcount = 0; __pyx_pybuffernd_buf.data = NULL; __pyx_pybuffernd_buf.rcbuffer = &__pyx_pybuffer_buf; /* "dataRead.pyx":165 - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset): - * cdef np.ndarray[np.uint8_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset): + * cdef np.ndarray[np.uint8_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array # <<<<<<<<<<<<<< * cdef unsigned long long i - * cdef unsigned char mask = ((1 << bitCount) - 1) + * cdef unsigned char mask = ((1 << bit_count) - 1) */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 165, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 165, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_numberOfRecords); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 165, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_number_of_records); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 165, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 165, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); @@ -3935,7 +3950,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUChar(char const *__pyx __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 165, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 165, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_record_format) < 0) __PYX_ERR(0, 165, __pyx_L1_error) __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 165, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; @@ -3956,60 +3971,60 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUChar(char const *__pyx __pyx_t_4 = 0; /* "dataRead.pyx":167 - * cdef np.ndarray[np.uint8_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array + * cdef np.ndarray[np.uint8_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array * cdef unsigned long long i - * cdef unsigned char mask = ((1 << bitCount) - 1) # <<<<<<<<<<<<<< + * cdef unsigned char mask = ((1 << bit_count) - 1) # <<<<<<<<<<<<<< * cdef unsigned char temp1byte = 0 - * if bitCount == 8: + * if bit_count == 8: */ - __pyx_v_mask = ((1 << __pyx_v_bitCount) - 1); + __pyx_v_mask = ((1 << __pyx_v_bit_count) - 1); /* "dataRead.pyx":168 * cdef unsigned long long i - * cdef unsigned char mask = ((1 << bitCount) - 1) + * cdef unsigned char mask = ((1 << bit_count) - 1) * cdef unsigned char temp1byte = 0 # <<<<<<<<<<<<<< - * if bitCount == 8: - * for i in range(numberOfRecords): + * if bit_count == 8: + * for i in range(number_of_records): */ __pyx_v_temp1byte = 0; /* "dataRead.pyx":169 - * cdef unsigned char mask = ((1 << bitCount) - 1) + * cdef unsigned char mask = ((1 << bit_count) - 1) * cdef unsigned char temp1byte = 0 - * if bitCount == 8: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp1byte, &bita[posByteBeg + record_byte_size * i], 1) + * if bit_count == 8: # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp1byte, &bit_stream[pos_byte_beg + record_byte_size * i], 1) */ - __pyx_t_6 = ((__pyx_v_bitCount == 8) != 0); + __pyx_t_6 = ((__pyx_v_bit_count == 8) != 0); if (__pyx_t_6) { /* "dataRead.pyx":170 * cdef unsigned char temp1byte = 0 - * if bitCount == 8: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp1byte, &bita[posByteBeg + record_byte_size * i], 1) + * if bit_count == 8: + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp1byte, &bit_stream[pos_byte_beg + record_byte_size * i], 1) * buf[i] = temp1byte */ - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":171 - * if bitCount == 8: - * for i in range(numberOfRecords): - * memcpy(&temp1byte, &bita[posByteBeg + record_byte_size * i], 1) # <<<<<<<<<<<<<< + * if bit_count == 8: + * for i in range(number_of_records): + * memcpy(&temp1byte, &bit_stream[pos_byte_beg + record_byte_size * i], 1) # <<<<<<<<<<<<<< * buf[i] = temp1byte * else: */ - (void)(memcpy((&__pyx_v_temp1byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), 1)); + (void)(memcpy((&__pyx_v_temp1byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), 1)); /* "dataRead.pyx":172 - * for i in range(numberOfRecords): - * memcpy(&temp1byte, &bita[posByteBeg + record_byte_size * i], 1) + * for i in range(number_of_records): + * memcpy(&temp1byte, &bit_stream[pos_byte_beg + record_byte_size * i], 1) * buf[i] = temp1byte # <<<<<<<<<<<<<< * else: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ __pyx_t_10 = __pyx_v_i; __pyx_t_11 = -1; @@ -4022,11 +4037,11 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUChar(char const *__pyx } /* "dataRead.pyx":169 - * cdef unsigned char mask = ((1 << bitCount) - 1) + * cdef unsigned char mask = ((1 << bit_count) - 1) * cdef unsigned char temp1byte = 0 - * if bitCount == 8: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp1byte, &bita[posByteBeg + record_byte_size * i], 1) + * if bit_count == 8: # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp1byte, &bit_stream[pos_byte_beg + record_byte_size * i], 1) */ goto __pyx_L3; } @@ -4034,55 +4049,55 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUChar(char const *__pyx /* "dataRead.pyx":174 * buf[i] = temp1byte * else: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp1byte, &bita[posByteBeg + record_byte_size * i], 1) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp1byte, &bit_stream[pos_byte_beg + record_byte_size * i], 1) * # right shift */ /*else*/ { - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":175 * else: - * for i in range(numberOfRecords): - * memcpy(&temp1byte, &bita[posByteBeg + record_byte_size * i], 1) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp1byte, &bit_stream[pos_byte_beg + record_byte_size * i], 1) # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ - (void)(memcpy((&__pyx_v_temp1byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), 1)); + (void)(memcpy((&__pyx_v_temp1byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), 1)); /* "dataRead.pyx":177 - * memcpy(&temp1byte, &bita[posByteBeg + record_byte_size * i], 1) + * memcpy(&temp1byte, &bit_stream[pos_byte_beg + record_byte_size * i], 1) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp1byte = temp1byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp1byte = temp1byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":178 * # right shift - * if bitOffset > 0: - * temp1byte = temp1byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp1byte = temp1byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part * temp1byte &= mask */ - __pyx_v_temp1byte = (__pyx_v_temp1byte >> __pyx_v_bitOffset); + __pyx_v_temp1byte = (__pyx_v_temp1byte >> __pyx_v_bit_offset); /* "dataRead.pyx":177 - * memcpy(&temp1byte, &bita[posByteBeg + record_byte_size * i], 1) + * memcpy(&temp1byte, &bit_stream[pos_byte_beg + record_byte_size * i], 1) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp1byte = temp1byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp1byte = temp1byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":180 - * temp1byte = temp1byte >> bitOffset + * temp1byte = temp1byte >> bit_offset * # mask left part * temp1byte &= mask # <<<<<<<<<<<<<< * buf[i] = temp1byte @@ -4114,7 +4129,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUChar(char const *__pyx * buf[i] = temp1byte * return buf # <<<<<<<<<<<<<< * - * cdef inline dataReadChar(const char* bita, str RecordFormat, unsigned long long numberOfRecords, + * cdef inline read_signed_char(const char* bit_stream, str record_format, unsigned long long number_of_records, */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject *)__pyx_v_buf)); @@ -4124,9 +4139,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUChar(char const *__pyx /* "dataRead.pyx":162 * return buf.byteswap() * - * cdef inline dataReadUChar(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset): + * cdef inline read_unsigned_char(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset): */ /* function exit code */ @@ -4141,7 +4156,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUChar(char const *__pyx __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_buf.rcbuffer->pybuffer); __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} - __Pyx_AddTraceback("dataRead.dataReadUChar", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("dataRead.read_unsigned_char", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; goto __pyx_L2; __pyx_L0:; @@ -4156,19 +4171,19 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUChar(char const *__pyx /* "dataRead.pyx":184 * return buf * - * cdef inline dataReadChar(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset): + * cdef inline read_signed_char(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset): */ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadChar(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_bitCount, unsigned char __pyx_v_bitOffset) { +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_signed_char(char const *__pyx_v_bit_stream, PyObject *__pyx_v_record_format, unsigned PY_LONG_LONG __pyx_v_number_of_records, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_pos_byte_beg, unsigned long __pyx_v_bit_count, unsigned char __pyx_v_bit_offset) { PyArrayObject *__pyx_v_buf = 0; unsigned PY_LONG_LONG __pyx_v_i; char __pyx_v_mask; char __pyx_v_temp1byte; - char __pyx_v_signBit; - char __pyx_v_signBitMask; - char __pyx_v_signExtend; + char __pyx_v_sign_bit; + char __pyx_v_sign_bit_mask; + char __pyx_v_sign_extend; __Pyx_LocalBuf_ND __pyx_pybuffernd_buf; __Pyx_Buffer __pyx_pybuffer_buf; PyObject *__pyx_r = NULL; @@ -4185,25 +4200,25 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadChar(char const *__pyx_ unsigned PY_LONG_LONG __pyx_t_10; int __pyx_t_11; unsigned PY_LONG_LONG __pyx_t_12; - __Pyx_RefNannySetupContext("dataReadChar", 0); + __Pyx_RefNannySetupContext("read_signed_char", 0); __pyx_pybuffer_buf.pybuffer.buf = NULL; __pyx_pybuffer_buf.refcount = 0; __pyx_pybuffernd_buf.data = NULL; __pyx_pybuffernd_buf.rcbuffer = &__pyx_pybuffer_buf; /* "dataRead.pyx":187 - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset): - * cdef np.ndarray[np.int8_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset): + * cdef np.ndarray[np.int8_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array # <<<<<<<<<<<<<< * cdef unsigned long long i - * cdef char mask = ((1 << bitCount) - 1) + * cdef char mask = ((1 << bit_count) - 1) */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 187, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 187, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_numberOfRecords); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 187, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_number_of_records); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 187, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 187, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); @@ -4212,7 +4227,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadChar(char const *__pyx_ __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 187, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 187, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_record_format) < 0) __PYX_ERR(0, 187, __pyx_L1_error) __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 187, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; @@ -4233,87 +4248,87 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadChar(char const *__pyx_ __pyx_t_4 = 0; /* "dataRead.pyx":189 - * cdef np.ndarray[np.int8_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array + * cdef np.ndarray[np.int8_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array * cdef unsigned long long i - * cdef char mask = ((1 << bitCount) - 1) # <<<<<<<<<<<<<< + * cdef char mask = ((1 << bit_count) - 1) # <<<<<<<<<<<<<< * cdef char temp1byte = 0 - * cdef char signBit = 0 + * cdef char sign_bit = 0 */ - __pyx_v_mask = ((1 << __pyx_v_bitCount) - 1); + __pyx_v_mask = ((1 << __pyx_v_bit_count) - 1); /* "dataRead.pyx":190 * cdef unsigned long long i - * cdef char mask = ((1 << bitCount) - 1) + * cdef char mask = ((1 << bit_count) - 1) * cdef char temp1byte = 0 # <<<<<<<<<<<<<< - * cdef char signBit = 0 - * cdef char signBitMask = (1 << (bitCount-1)) + * cdef char sign_bit = 0 + * cdef char sign_bit_mask = (1 << (bit_count-1)) */ __pyx_v_temp1byte = 0; /* "dataRead.pyx":191 - * cdef char mask = ((1 << bitCount) - 1) + * cdef char mask = ((1 << bit_count) - 1) * cdef char temp1byte = 0 - * cdef char signBit = 0 # <<<<<<<<<<<<<< - * cdef char signBitMask = (1 << (bitCount-1)) - * cdef char signExtend = ((1 << (8 - bitCount)) - 1) << bitCount + * cdef char sign_bit = 0 # <<<<<<<<<<<<<< + * cdef char sign_bit_mask = (1 << (bit_count-1)) + * cdef char sign_extend = ((1 << (8 - bit_count)) - 1) << bit_count */ - __pyx_v_signBit = 0; + __pyx_v_sign_bit = 0; /* "dataRead.pyx":192 * cdef char temp1byte = 0 - * cdef char signBit = 0 - * cdef char signBitMask = (1 << (bitCount-1)) # <<<<<<<<<<<<<< - * cdef char signExtend = ((1 << (8 - bitCount)) - 1) << bitCount - * if bitCount == 8: + * cdef char sign_bit = 0 + * cdef char sign_bit_mask = (1 << (bit_count-1)) # <<<<<<<<<<<<<< + * cdef char sign_extend = ((1 << (8 - bit_count)) - 1) << bit_count + * if bit_count == 8: */ - __pyx_v_signBitMask = (1 << (__pyx_v_bitCount - 1)); + __pyx_v_sign_bit_mask = (1 << (__pyx_v_bit_count - 1)); /* "dataRead.pyx":193 - * cdef char signBit = 0 - * cdef char signBitMask = (1 << (bitCount-1)) - * cdef char signExtend = ((1 << (8 - bitCount)) - 1) << bitCount # <<<<<<<<<<<<<< - * if bitCount == 8: - * for i in range(numberOfRecords): + * cdef char sign_bit = 0 + * cdef char sign_bit_mask = (1 << (bit_count-1)) + * cdef char sign_extend = ((1 << (8 - bit_count)) - 1) << bit_count # <<<<<<<<<<<<<< + * if bit_count == 8: + * for i in range(number_of_records): */ - __pyx_v_signExtend = (((1 << (8 - __pyx_v_bitCount)) - 1) << __pyx_v_bitCount); + __pyx_v_sign_extend = (((1 << (8 - __pyx_v_bit_count)) - 1) << __pyx_v_bit_count); /* "dataRead.pyx":194 - * cdef char signBitMask = (1 << (bitCount-1)) - * cdef char signExtend = ((1 << (8 - bitCount)) - 1) << bitCount - * if bitCount == 8: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp1byte, &bita[posByteBeg + record_byte_size * i], 1) + * cdef char sign_bit_mask = (1 << (bit_count-1)) + * cdef char sign_extend = ((1 << (8 - bit_count)) - 1) << bit_count + * if bit_count == 8: # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp1byte, &bit_stream[pos_byte_beg + record_byte_size * i], 1) */ - __pyx_t_6 = ((__pyx_v_bitCount == 8) != 0); + __pyx_t_6 = ((__pyx_v_bit_count == 8) != 0); if (__pyx_t_6) { /* "dataRead.pyx":195 - * cdef char signExtend = ((1 << (8 - bitCount)) - 1) << bitCount - * if bitCount == 8: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp1byte, &bita[posByteBeg + record_byte_size * i], 1) + * cdef char sign_extend = ((1 << (8 - bit_count)) - 1) << bit_count + * if bit_count == 8: + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp1byte, &bit_stream[pos_byte_beg + record_byte_size * i], 1) * buf[i] = temp1byte */ - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":196 - * if bitCount == 8: - * for i in range(numberOfRecords): - * memcpy(&temp1byte, &bita[posByteBeg + record_byte_size * i], 1) # <<<<<<<<<<<<<< + * if bit_count == 8: + * for i in range(number_of_records): + * memcpy(&temp1byte, &bit_stream[pos_byte_beg + record_byte_size * i], 1) # <<<<<<<<<<<<<< * buf[i] = temp1byte * else: */ - (void)(memcpy((&__pyx_v_temp1byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), 1)); + (void)(memcpy((&__pyx_v_temp1byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), 1)); /* "dataRead.pyx":197 - * for i in range(numberOfRecords): - * memcpy(&temp1byte, &bita[posByteBeg + record_byte_size * i], 1) + * for i in range(number_of_records): + * memcpy(&temp1byte, &bit_stream[pos_byte_beg + record_byte_size * i], 1) * buf[i] = temp1byte # <<<<<<<<<<<<<< * else: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ __pyx_t_10 = __pyx_v_i; __pyx_t_11 = -1; @@ -4326,11 +4341,11 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadChar(char const *__pyx_ } /* "dataRead.pyx":194 - * cdef char signBitMask = (1 << (bitCount-1)) - * cdef char signExtend = ((1 << (8 - bitCount)) - 1) << bitCount - * if bitCount == 8: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp1byte, &bita[posByteBeg + record_byte_size * i], 1) + * cdef char sign_bit_mask = (1 << (bit_count-1)) + * cdef char sign_extend = ((1 << (8 - bit_count)) - 1) << bit_count + * if bit_count == 8: # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp1byte, &bit_stream[pos_byte_beg + record_byte_size * i], 1) */ goto __pyx_L3; } @@ -4338,102 +4353,102 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadChar(char const *__pyx_ /* "dataRead.pyx":199 * buf[i] = temp1byte * else: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp1byte, &bita[posByteBeg + record_byte_size * i], 1) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp1byte, &bit_stream[pos_byte_beg + record_byte_size * i], 1) * # right shift */ /*else*/ { - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":200 * else: - * for i in range(numberOfRecords): - * memcpy(&temp1byte, &bita[posByteBeg + record_byte_size * i], 1) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp1byte, &bit_stream[pos_byte_beg + record_byte_size * i], 1) # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ - (void)(memcpy((&__pyx_v_temp1byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), 1)); + (void)(memcpy((&__pyx_v_temp1byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), 1)); /* "dataRead.pyx":202 - * memcpy(&temp1byte, &bita[posByteBeg + record_byte_size * i], 1) + * memcpy(&temp1byte, &bit_stream[pos_byte_beg + record_byte_size * i], 1) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp1byte = temp1byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp1byte = temp1byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":203 * # right shift - * if bitOffset > 0: - * temp1byte = temp1byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp1byte = temp1byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part * temp1byte &= mask */ - __pyx_v_temp1byte = (__pyx_v_temp1byte >> __pyx_v_bitOffset); + __pyx_v_temp1byte = (__pyx_v_temp1byte >> __pyx_v_bit_offset); /* "dataRead.pyx":202 - * memcpy(&temp1byte, &bita[posByteBeg + record_byte_size * i], 1) + * memcpy(&temp1byte, &bit_stream[pos_byte_beg + record_byte_size * i], 1) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp1byte = temp1byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp1byte = temp1byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":205 - * temp1byte = temp1byte >> bitOffset + * temp1byte = temp1byte >> bit_offset * # mask left part * temp1byte &= mask # <<<<<<<<<<<<<< - * signBit = temp1byte & signBitMask - * if signBit: # negative value, sign extend + * sign_bit = temp1byte & sign_bit_mask + * if sign_bit: # negative value, sign extend */ __pyx_v_temp1byte = (__pyx_v_temp1byte & __pyx_v_mask); /* "dataRead.pyx":206 * # mask left part * temp1byte &= mask - * signBit = temp1byte & signBitMask # <<<<<<<<<<<<<< - * if signBit: # negative value, sign extend - * temp1byte |= signExtend + * sign_bit = temp1byte & sign_bit_mask # <<<<<<<<<<<<<< + * if sign_bit: # negative value, sign extend + * temp1byte |= sign_extend */ - __pyx_v_signBit = (__pyx_v_temp1byte & __pyx_v_signBitMask); + __pyx_v_sign_bit = (__pyx_v_temp1byte & __pyx_v_sign_bit_mask); /* "dataRead.pyx":207 * temp1byte &= mask - * signBit = temp1byte & signBitMask - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp1byte |= signExtend + * sign_bit = temp1byte & sign_bit_mask + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp1byte |= sign_extend * buf[i] = temp1byte */ - __pyx_t_6 = (__pyx_v_signBit != 0); + __pyx_t_6 = (__pyx_v_sign_bit != 0); if (__pyx_t_6) { /* "dataRead.pyx":208 - * signBit = temp1byte & signBitMask - * if signBit: # negative value, sign extend - * temp1byte |= signExtend # <<<<<<<<<<<<<< + * sign_bit = temp1byte & sign_bit_mask + * if sign_bit: # negative value, sign extend + * temp1byte |= sign_extend # <<<<<<<<<<<<<< * buf[i] = temp1byte * return buf */ - __pyx_v_temp1byte = (__pyx_v_temp1byte | __pyx_v_signExtend); + __pyx_v_temp1byte = (__pyx_v_temp1byte | __pyx_v_sign_extend); /* "dataRead.pyx":207 * temp1byte &= mask - * signBit = temp1byte & signBitMask - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp1byte |= signExtend + * sign_bit = temp1byte & sign_bit_mask + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp1byte |= sign_extend * buf[i] = temp1byte */ } /* "dataRead.pyx":209 - * if signBit: # negative value, sign extend - * temp1byte |= signExtend + * if sign_bit: # negative value, sign extend + * temp1byte |= sign_extend * buf[i] = temp1byte # <<<<<<<<<<<<<< * return buf * @@ -4451,11 +4466,11 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadChar(char const *__pyx_ __pyx_L3:; /* "dataRead.pyx":210 - * temp1byte |= signExtend + * temp1byte |= sign_extend * buf[i] = temp1byte * return buf # <<<<<<<<<<<<<< * - * cdef inline dataReadUShort(const char* bita, str RecordFormat, unsigned long long numberOfRecords, + * cdef inline read_unsigned_short(const char* bit_stream, str record_format, unsigned long long number_of_records, */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject *)__pyx_v_buf)); @@ -4465,9 +4480,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadChar(char const *__pyx_ /* "dataRead.pyx":184 * return buf * - * cdef inline dataReadChar(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset): + * cdef inline read_signed_char(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset): */ /* function exit code */ @@ -4482,7 +4497,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadChar(char const *__pyx_ __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_buf.rcbuffer->pybuffer); __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} - __Pyx_AddTraceback("dataRead.dataReadChar", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("dataRead.read_signed_char", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; goto __pyx_L2; __pyx_L0:; @@ -4497,12 +4512,12 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadChar(char const *__pyx_ /* "dataRead.pyx":212 * return buf * - * cdef inline dataReadUShort(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): + * cdef inline read_unsigned_short(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset, unsigned char swap): */ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUShort(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_bitCount, unsigned char __pyx_v_bitOffset, unsigned char __pyx_v_swap) { +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_unsigned_short(char const *__pyx_v_bit_stream, PyObject *__pyx_v_record_format, unsigned PY_LONG_LONG __pyx_v_number_of_records, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_pos_byte_beg, unsigned long __pyx_v_bit_count, unsigned char __pyx_v_bit_offset, unsigned char __pyx_v_swap) { PyArrayObject *__pyx_v_buf = 0; unsigned PY_LONG_LONG __pyx_v_i; unsigned short __pyx_v_mask; @@ -4525,25 +4540,25 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUShort(char const *__py int __pyx_t_11; unsigned PY_LONG_LONG __pyx_t_12; unsigned PY_LONG_LONG __pyx_t_13; - __Pyx_RefNannySetupContext("dataReadUShort", 0); + __Pyx_RefNannySetupContext("read_unsigned_short", 0); __pyx_pybuffer_buf.pybuffer.buf = NULL; __pyx_pybuffer_buf.refcount = 0; __pyx_pybuffernd_buf.data = NULL; __pyx_pybuffernd_buf.rcbuffer = &__pyx_pybuffer_buf; /* "dataRead.pyx":215 - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): - * cdef np.ndarray[np.uint16_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset, unsigned char swap): + * cdef np.ndarray[np.uint16_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array # <<<<<<<<<<<<<< * cdef unsigned long long i - * cdef unsigned short mask = ((1 << bitCount) - 1) + * cdef unsigned short mask = ((1 << bit_count) - 1) */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 215, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 215, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_numberOfRecords); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 215, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_number_of_records); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 215, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 215, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); @@ -4552,7 +4567,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUShort(char const *__py __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 215, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 215, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_record_format) < 0) __PYX_ERR(0, 215, __pyx_L1_error) __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 215, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; @@ -4573,57 +4588,57 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUShort(char const *__py __pyx_t_4 = 0; /* "dataRead.pyx":217 - * cdef np.ndarray[np.uint16_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array + * cdef np.ndarray[np.uint16_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array * cdef unsigned long long i - * cdef unsigned short mask = ((1 << bitCount) - 1) # <<<<<<<<<<<<<< + * cdef unsigned short mask = ((1 << bit_count) - 1) # <<<<<<<<<<<<<< * cdef unsigned short temp2byte = 0 * cdef char temp[2] */ - __pyx_v_mask = ((1 << __pyx_v_bitCount) - 1); + __pyx_v_mask = ((1 << __pyx_v_bit_count) - 1); /* "dataRead.pyx":218 * cdef unsigned long long i - * cdef unsigned short mask = ((1 << bitCount) - 1) + * cdef unsigned short mask = ((1 << bit_count) - 1) * cdef unsigned short temp2byte = 0 # <<<<<<<<<<<<<< * cdef char temp[2] - * if bitCount == 16: + * if bit_count == 16: */ __pyx_v_temp2byte = 0; /* "dataRead.pyx":220 * cdef unsigned short temp2byte = 0 * cdef char temp[2] - * if bitCount == 16: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + * if bit_count == 16: # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) */ - __pyx_t_6 = ((__pyx_v_bitCount == 16) != 0); + __pyx_t_6 = ((__pyx_v_bit_count == 16) != 0); if (__pyx_t_6) { /* "dataRead.pyx":221 * cdef char temp[2] - * if bitCount == 16: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + * if bit_count == 16: + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) * buf[i] = temp2byte */ - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":222 - * if bitCount == 16: - * for i in range(numberOfRecords): - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) # <<<<<<<<<<<<<< + * if bit_count == 16: + * for i in range(number_of_records): + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) # <<<<<<<<<<<<<< * buf[i] = temp2byte * if swap == 0: */ - (void)(memcpy((&__pyx_v_temp2byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), 2)); + (void)(memcpy((&__pyx_v_temp2byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), 2)); /* "dataRead.pyx":223 - * for i in range(numberOfRecords): - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + * for i in range(number_of_records): + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) * buf[i] = temp2byte # <<<<<<<<<<<<<< * if swap == 0: * return buf @@ -4639,7 +4654,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUShort(char const *__py } /* "dataRead.pyx":224 - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) * buf[i] = temp2byte * if swap == 0: # <<<<<<<<<<<<<< * return buf @@ -4661,7 +4676,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUShort(char const *__py goto __pyx_L0; /* "dataRead.pyx":224 - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) * buf[i] = temp2byte * if swap == 0: # <<<<<<<<<<<<<< * return buf @@ -4706,9 +4721,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUShort(char const *__py /* "dataRead.pyx":220 * cdef unsigned short temp2byte = 0 * cdef char temp[2] - * if bitCount == 16: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + * if bit_count == 16: # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) */ } @@ -4716,8 +4731,8 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUShort(char const *__py * return buf.byteswap() * else: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + * for i in range(number_of_records): + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) */ /*else*/ { __pyx_t_6 = ((__pyx_v_swap == 0) != 0); @@ -4726,65 +4741,65 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUShort(char const *__py /* "dataRead.pyx":230 * else: * if swap == 0: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) * # right shift */ - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":231 * if swap == 0: - * for i in range(numberOfRecords): - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ - (void)(memcpy((&__pyx_v_temp2byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), 2)); + (void)(memcpy((&__pyx_v_temp2byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), 2)); /* "dataRead.pyx":233 - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp2byte = temp2byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp2byte = temp2byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":234 * # right shift - * if bitOffset > 0: - * temp2byte = temp2byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp2byte = temp2byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 16: + * if bit_count < 16: */ - __pyx_v_temp2byte = (__pyx_v_temp2byte >> __pyx_v_bitOffset); + __pyx_v_temp2byte = (__pyx_v_temp2byte >> __pyx_v_bit_offset); /* "dataRead.pyx":233 - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp2byte = temp2byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp2byte = temp2byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":236 - * temp2byte = temp2byte >> bitOffset + * temp2byte = temp2byte >> bit_offset * # mask left part - * if bitCount < 16: # <<<<<<<<<<<<<< + * if bit_count < 16: # <<<<<<<<<<<<<< * temp2byte &= mask * buf[i] = temp2byte */ - __pyx_t_6 = ((__pyx_v_bitCount < 16) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 16) != 0); if (__pyx_t_6) { /* "dataRead.pyx":237 * # mask left part - * if bitCount < 16: + * if bit_count < 16: * temp2byte &= mask # <<<<<<<<<<<<<< * buf[i] = temp2byte * else: @@ -4792,20 +4807,20 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUShort(char const *__py __pyx_v_temp2byte = (__pyx_v_temp2byte & __pyx_v_mask); /* "dataRead.pyx":236 - * temp2byte = temp2byte >> bitOffset + * temp2byte = temp2byte >> bit_offset * # mask left part - * if bitCount < 16: # <<<<<<<<<<<<<< + * if bit_count < 16: # <<<<<<<<<<<<<< * temp2byte &= mask * buf[i] = temp2byte */ } /* "dataRead.pyx":238 - * if bitCount < 16: + * if bit_count < 16: * temp2byte &= mask * buf[i] = temp2byte # <<<<<<<<<<<<<< * else: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ __pyx_t_12 = __pyx_v_i; __pyx_t_11 = -1; @@ -4821,8 +4836,8 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUShort(char const *__py * return buf.byteswap() * else: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + * for i in range(number_of_records): + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) */ goto __pyx_L7; } @@ -4830,75 +4845,75 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUShort(char const *__py /* "dataRead.pyx":240 * buf[i] = temp2byte * else: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp, &bita[posByteBeg + record_byte_size * i], 2) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp, &bit_stream[pos_byte_beg + record_byte_size * i], 2) * temp2byte = temp[0]<<8 | temp[1] # swap bytes */ /*else*/ { - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":241 * else: - * for i in range(numberOfRecords): - * memcpy(&temp, &bita[posByteBeg + record_byte_size * i], 2) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp, &bit_stream[pos_byte_beg + record_byte_size * i], 2) # <<<<<<<<<<<<<< * temp2byte = temp[0]<<8 | temp[1] # swap bytes * # right shift */ - (void)(memcpy((&__pyx_v_temp), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), 2)); + (void)(memcpy((&__pyx_v_temp), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), 2)); /* "dataRead.pyx":242 - * for i in range(numberOfRecords): - * memcpy(&temp, &bita[posByteBeg + record_byte_size * i], 2) + * for i in range(number_of_records): + * memcpy(&temp, &bit_stream[pos_byte_beg + record_byte_size * i], 2) * temp2byte = temp[0]<<8 | temp[1] # swap bytes # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ __pyx_v_temp2byte = (((__pyx_v_temp[0]) << 8) | (__pyx_v_temp[1])); /* "dataRead.pyx":244 * temp2byte = temp[0]<<8 | temp[1] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp2byte = temp2byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp2byte = temp2byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":245 * # right shift - * if bitOffset > 0: - * temp2byte = temp2byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp2byte = temp2byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 16: + * if bit_count < 16: */ - __pyx_v_temp2byte = (__pyx_v_temp2byte >> __pyx_v_bitOffset); + __pyx_v_temp2byte = (__pyx_v_temp2byte >> __pyx_v_bit_offset); /* "dataRead.pyx":244 * temp2byte = temp[0]<<8 | temp[1] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp2byte = temp2byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp2byte = temp2byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":247 - * temp2byte = temp2byte >> bitOffset + * temp2byte = temp2byte >> bit_offset * # mask left part - * if bitCount < 16: # <<<<<<<<<<<<<< + * if bit_count < 16: # <<<<<<<<<<<<<< * temp2byte &= mask * buf[i] = temp2byte */ - __pyx_t_6 = ((__pyx_v_bitCount < 16) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 16) != 0); if (__pyx_t_6) { /* "dataRead.pyx":248 * # mask left part - * if bitCount < 16: + * if bit_count < 16: * temp2byte &= mask # <<<<<<<<<<<<<< * buf[i] = temp2byte * return buf @@ -4906,16 +4921,16 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUShort(char const *__py __pyx_v_temp2byte = (__pyx_v_temp2byte & __pyx_v_mask); /* "dataRead.pyx":247 - * temp2byte = temp2byte >> bitOffset + * temp2byte = temp2byte >> bit_offset * # mask left part - * if bitCount < 16: # <<<<<<<<<<<<<< + * if bit_count < 16: # <<<<<<<<<<<<<< * temp2byte &= mask * buf[i] = temp2byte */ } /* "dataRead.pyx":249 - * if bitCount < 16: + * if bit_count < 16: * temp2byte &= mask * buf[i] = temp2byte # <<<<<<<<<<<<<< * return buf @@ -4938,7 +4953,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUShort(char const *__py * buf[i] = temp2byte * return buf # <<<<<<<<<<<<<< * - * cdef inline dataReadShort(const char* bita, str RecordFormat, unsigned long long numberOfRecords, + * cdef inline read_signed_short(const char* bit_stream, str record_format, unsigned long long number_of_records, */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject *)__pyx_v_buf)); @@ -4949,9 +4964,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUShort(char const *__py /* "dataRead.pyx":212 * return buf * - * cdef inline dataReadUShort(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): + * cdef inline read_unsigned_short(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset, unsigned char swap): */ /* function exit code */ @@ -4966,7 +4981,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUShort(char const *__py __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_buf.rcbuffer->pybuffer); __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} - __Pyx_AddTraceback("dataRead.dataReadUShort", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("dataRead.read_unsigned_short", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; goto __pyx_L2; __pyx_L0:; @@ -4981,19 +4996,19 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUShort(char const *__py /* "dataRead.pyx":252 * return buf * - * cdef inline dataReadShort(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): + * cdef inline read_signed_short(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset, unsigned char swap): */ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadShort(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_bitCount, unsigned char __pyx_v_bitOffset, unsigned char __pyx_v_swap) { +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_signed_short(char const *__pyx_v_bit_stream, PyObject *__pyx_v_record_format, unsigned PY_LONG_LONG __pyx_v_number_of_records, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_pos_byte_beg, unsigned long __pyx_v_bit_count, unsigned char __pyx_v_bit_offset, unsigned char __pyx_v_swap) { PyArrayObject *__pyx_v_buf = 0; unsigned PY_LONG_LONG __pyx_v_i; short __pyx_v_mask; short __pyx_v_temp2byte; - short __pyx_v_signBit; - short __pyx_v_signBitMask; - short __pyx_v_signExtend; + short __pyx_v_sign_bit; + short __pyx_v_sign_bit_mask; + short __pyx_v_sign_extend; char __pyx_v_temp[2]; __Pyx_LocalBuf_ND __pyx_pybuffernd_buf; __Pyx_Buffer __pyx_pybuffer_buf; @@ -5012,25 +5027,25 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadShort(char const *__pyx int __pyx_t_11; unsigned PY_LONG_LONG __pyx_t_12; unsigned PY_LONG_LONG __pyx_t_13; - __Pyx_RefNannySetupContext("dataReadShort", 0); + __Pyx_RefNannySetupContext("read_signed_short", 0); __pyx_pybuffer_buf.pybuffer.buf = NULL; __pyx_pybuffer_buf.refcount = 0; __pyx_pybuffernd_buf.data = NULL; __pyx_pybuffernd_buf.rcbuffer = &__pyx_pybuffer_buf; /* "dataRead.pyx":255 - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): - * cdef np.ndarray[np.int16_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset, unsigned char swap): + * cdef np.ndarray[np.int16_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array # <<<<<<<<<<<<<< * cdef unsigned long long i - * cdef short mask = ((1 << bitCount) - 1) + * cdef short mask = ((1 << bit_count) - 1) */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 255, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 255, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_numberOfRecords); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 255, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_number_of_records); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 255, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 255, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); @@ -5039,7 +5054,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadShort(char const *__pyx __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 255, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 255, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_record_format) < 0) __PYX_ERR(0, 255, __pyx_L1_error) __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 255, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; @@ -5060,84 +5075,84 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadShort(char const *__pyx __pyx_t_4 = 0; /* "dataRead.pyx":257 - * cdef np.ndarray[np.int16_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array + * cdef np.ndarray[np.int16_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array * cdef unsigned long long i - * cdef short mask = ((1 << bitCount) - 1) # <<<<<<<<<<<<<< + * cdef short mask = ((1 << bit_count) - 1) # <<<<<<<<<<<<<< * cdef short temp2byte = 0 - * cdef short signBit = 0 + * cdef short sign_bit = 0 */ - __pyx_v_mask = ((1 << __pyx_v_bitCount) - 1); + __pyx_v_mask = ((1 << __pyx_v_bit_count) - 1); /* "dataRead.pyx":258 * cdef unsigned long long i - * cdef short mask = ((1 << bitCount) - 1) + * cdef short mask = ((1 << bit_count) - 1) * cdef short temp2byte = 0 # <<<<<<<<<<<<<< - * cdef short signBit = 0 - * cdef short signBitMask = (1 << (bitCount-1)) + * cdef short sign_bit = 0 + * cdef short sign_bit_mask = (1 << (bit_count-1)) */ __pyx_v_temp2byte = 0; /* "dataRead.pyx":259 - * cdef short mask = ((1 << bitCount) - 1) + * cdef short mask = ((1 << bit_count) - 1) * cdef short temp2byte = 0 - * cdef short signBit = 0 # <<<<<<<<<<<<<< - * cdef short signBitMask = (1 << (bitCount-1)) - * cdef short signExtend = ((1 << (16 - bitCount)) - 1) << bitCount + * cdef short sign_bit = 0 # <<<<<<<<<<<<<< + * cdef short sign_bit_mask = (1 << (bit_count-1)) + * cdef short sign_extend = ((1 << (16 - bit_count)) - 1) << bit_count */ - __pyx_v_signBit = 0; + __pyx_v_sign_bit = 0; /* "dataRead.pyx":260 * cdef short temp2byte = 0 - * cdef short signBit = 0 - * cdef short signBitMask = (1 << (bitCount-1)) # <<<<<<<<<<<<<< - * cdef short signExtend = ((1 << (16 - bitCount)) - 1) << bitCount + * cdef short sign_bit = 0 + * cdef short sign_bit_mask = (1 << (bit_count-1)) # <<<<<<<<<<<<<< + * cdef short sign_extend = ((1 << (16 - bit_count)) - 1) << bit_count * cdef char temp[2] */ - __pyx_v_signBitMask = (1 << (__pyx_v_bitCount - 1)); + __pyx_v_sign_bit_mask = (1 << (__pyx_v_bit_count - 1)); /* "dataRead.pyx":261 - * cdef short signBit = 0 - * cdef short signBitMask = (1 << (bitCount-1)) - * cdef short signExtend = ((1 << (16 - bitCount)) - 1) << bitCount # <<<<<<<<<<<<<< + * cdef short sign_bit = 0 + * cdef short sign_bit_mask = (1 << (bit_count-1)) + * cdef short sign_extend = ((1 << (16 - bit_count)) - 1) << bit_count # <<<<<<<<<<<<<< * cdef char temp[2] - * if bitCount == 16: + * if bit_count == 16: */ - __pyx_v_signExtend = (((1 << (16 - __pyx_v_bitCount)) - 1) << __pyx_v_bitCount); + __pyx_v_sign_extend = (((1 << (16 - __pyx_v_bit_count)) - 1) << __pyx_v_bit_count); /* "dataRead.pyx":263 - * cdef short signExtend = ((1 << (16 - bitCount)) - 1) << bitCount + * cdef short sign_extend = ((1 << (16 - bit_count)) - 1) << bit_count * cdef char temp[2] - * if bitCount == 16: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + * if bit_count == 16: # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) */ - __pyx_t_6 = ((__pyx_v_bitCount == 16) != 0); + __pyx_t_6 = ((__pyx_v_bit_count == 16) != 0); if (__pyx_t_6) { /* "dataRead.pyx":264 * cdef char temp[2] - * if bitCount == 16: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + * if bit_count == 16: + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) * buf[i] = temp2byte */ - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":265 - * if bitCount == 16: - * for i in range(numberOfRecords): - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) # <<<<<<<<<<<<<< + * if bit_count == 16: + * for i in range(number_of_records): + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) # <<<<<<<<<<<<<< * buf[i] = temp2byte * if swap == 0: */ - (void)(memcpy((&__pyx_v_temp2byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), 2)); + (void)(memcpy((&__pyx_v_temp2byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), 2)); /* "dataRead.pyx":266 - * for i in range(numberOfRecords): - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + * for i in range(number_of_records): + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) * buf[i] = temp2byte # <<<<<<<<<<<<<< * if swap == 0: * return buf @@ -5153,7 +5168,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadShort(char const *__pyx } /* "dataRead.pyx":267 - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) * buf[i] = temp2byte * if swap == 0: # <<<<<<<<<<<<<< * return buf @@ -5175,7 +5190,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadShort(char const *__pyx goto __pyx_L0; /* "dataRead.pyx":267 - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) * buf[i] = temp2byte * if swap == 0: # <<<<<<<<<<<<<< * return buf @@ -5218,11 +5233,11 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadShort(char const *__pyx } /* "dataRead.pyx":263 - * cdef short signExtend = ((1 << (16 - bitCount)) - 1) << bitCount + * cdef short sign_extend = ((1 << (16 - bit_count)) - 1) << bit_count * cdef char temp[2] - * if bitCount == 16: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + * if bit_count == 16: # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) */ } @@ -5230,8 +5245,8 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadShort(char const *__pyx * return buf.byteswap() * else: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + * for i in range(number_of_records): + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) */ /*else*/ { __pyx_t_6 = ((__pyx_v_swap == 0) != 0); @@ -5240,104 +5255,104 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadShort(char const *__pyx /* "dataRead.pyx":273 * else: * if swap == 0: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) * # right shift */ - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":274 * if swap == 0: - * for i in range(numberOfRecords): - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ - (void)(memcpy((&__pyx_v_temp2byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), 2)); + (void)(memcpy((&__pyx_v_temp2byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), 2)); /* "dataRead.pyx":276 - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp2byte = temp2byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp2byte = temp2byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":277 * # right shift - * if bitOffset > 0: - * temp2byte = temp2byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp2byte = temp2byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part * temp2byte &= mask */ - __pyx_v_temp2byte = (__pyx_v_temp2byte >> __pyx_v_bitOffset); + __pyx_v_temp2byte = (__pyx_v_temp2byte >> __pyx_v_bit_offset); /* "dataRead.pyx":276 - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp2byte = temp2byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp2byte = temp2byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":279 - * temp2byte = temp2byte >> bitOffset + * temp2byte = temp2byte >> bit_offset * # mask left part * temp2byte &= mask # <<<<<<<<<<<<<< - * signBit = temp2byte & signBitMask - * if signBit: # negative value, sign extend + * sign_bit = temp2byte & sign_bit_mask + * if sign_bit: # negative value, sign extend */ __pyx_v_temp2byte = (__pyx_v_temp2byte & __pyx_v_mask); /* "dataRead.pyx":280 * # mask left part * temp2byte &= mask - * signBit = temp2byte & signBitMask # <<<<<<<<<<<<<< - * if signBit: # negative value, sign extend - * temp2byte |= signExtend + * sign_bit = temp2byte & sign_bit_mask # <<<<<<<<<<<<<< + * if sign_bit: # negative value, sign extend + * temp2byte |= sign_extend */ - __pyx_v_signBit = (__pyx_v_temp2byte & __pyx_v_signBitMask); + __pyx_v_sign_bit = (__pyx_v_temp2byte & __pyx_v_sign_bit_mask); /* "dataRead.pyx":281 * temp2byte &= mask - * signBit = temp2byte & signBitMask - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp2byte |= signExtend + * sign_bit = temp2byte & sign_bit_mask + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp2byte |= sign_extend * buf[i] = temp2byte */ - __pyx_t_6 = (__pyx_v_signBit != 0); + __pyx_t_6 = (__pyx_v_sign_bit != 0); if (__pyx_t_6) { /* "dataRead.pyx":282 - * signBit = temp2byte & signBitMask - * if signBit: # negative value, sign extend - * temp2byte |= signExtend # <<<<<<<<<<<<<< + * sign_bit = temp2byte & sign_bit_mask + * if sign_bit: # negative value, sign extend + * temp2byte |= sign_extend # <<<<<<<<<<<<<< * buf[i] = temp2byte * else: */ - __pyx_v_temp2byte = (__pyx_v_temp2byte | __pyx_v_signExtend); + __pyx_v_temp2byte = (__pyx_v_temp2byte | __pyx_v_sign_extend); /* "dataRead.pyx":281 * temp2byte &= mask - * signBit = temp2byte & signBitMask - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp2byte |= signExtend + * sign_bit = temp2byte & sign_bit_mask + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp2byte |= sign_extend * buf[i] = temp2byte */ } /* "dataRead.pyx":283 - * if signBit: # negative value, sign extend - * temp2byte |= signExtend + * if sign_bit: # negative value, sign extend + * temp2byte |= sign_extend * buf[i] = temp2byte # <<<<<<<<<<<<<< * else: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ __pyx_t_12 = __pyx_v_i; __pyx_t_11 = -1; @@ -5353,8 +5368,8 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadShort(char const *__pyx * return buf.byteswap() * else: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp2byte, &bita[posByteBeg + record_byte_size * i], 2) + * for i in range(number_of_records): + * memcpy(&temp2byte, &bit_stream[pos_byte_beg + record_byte_size * i], 2) */ goto __pyx_L7; } @@ -5362,111 +5377,111 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadShort(char const *__pyx /* "dataRead.pyx":285 * buf[i] = temp2byte * else: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp, &bita[posByteBeg + record_byte_size * i], 2) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp, &bit_stream[pos_byte_beg + record_byte_size * i], 2) * temp2byte = temp[0]<<8 | temp[1] # swap bytes */ /*else*/ { - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":286 * else: - * for i in range(numberOfRecords): - * memcpy(&temp, &bita[posByteBeg + record_byte_size * i], 2) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp, &bit_stream[pos_byte_beg + record_byte_size * i], 2) # <<<<<<<<<<<<<< * temp2byte = temp[0]<<8 | temp[1] # swap bytes * # right shift */ - (void)(memcpy((&__pyx_v_temp), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), 2)); + (void)(memcpy((&__pyx_v_temp), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), 2)); /* "dataRead.pyx":287 - * for i in range(numberOfRecords): - * memcpy(&temp, &bita[posByteBeg + record_byte_size * i], 2) + * for i in range(number_of_records): + * memcpy(&temp, &bit_stream[pos_byte_beg + record_byte_size * i], 2) * temp2byte = temp[0]<<8 | temp[1] # swap bytes # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ __pyx_v_temp2byte = (((__pyx_v_temp[0]) << 8) | (__pyx_v_temp[1])); /* "dataRead.pyx":289 * temp2byte = temp[0]<<8 | temp[1] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp2byte = temp2byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp2byte = temp2byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":290 * # right shift - * if bitOffset > 0: - * temp2byte = temp2byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp2byte = temp2byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part * temp2byte &= mask */ - __pyx_v_temp2byte = (__pyx_v_temp2byte >> __pyx_v_bitOffset); + __pyx_v_temp2byte = (__pyx_v_temp2byte >> __pyx_v_bit_offset); /* "dataRead.pyx":289 * temp2byte = temp[0]<<8 | temp[1] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp2byte = temp2byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp2byte = temp2byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":292 - * temp2byte = temp2byte >> bitOffset + * temp2byte = temp2byte >> bit_offset * # mask left part * temp2byte &= mask # <<<<<<<<<<<<<< - * signBit = temp2byte & signBitMask - * if signBit: # negative value, sign extend + * sign_bit = temp2byte & sign_bit_mask + * if sign_bit: # negative value, sign extend */ __pyx_v_temp2byte = (__pyx_v_temp2byte & __pyx_v_mask); /* "dataRead.pyx":293 * # mask left part * temp2byte &= mask - * signBit = temp2byte & signBitMask # <<<<<<<<<<<<<< - * if signBit: # negative value, sign extend - * temp2byte |= signExtend + * sign_bit = temp2byte & sign_bit_mask # <<<<<<<<<<<<<< + * if sign_bit: # negative value, sign extend + * temp2byte |= sign_extend */ - __pyx_v_signBit = (__pyx_v_temp2byte & __pyx_v_signBitMask); + __pyx_v_sign_bit = (__pyx_v_temp2byte & __pyx_v_sign_bit_mask); /* "dataRead.pyx":294 * temp2byte &= mask - * signBit = temp2byte & signBitMask - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp2byte |= signExtend + * sign_bit = temp2byte & sign_bit_mask + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp2byte |= sign_extend * buf[i] = temp2byte */ - __pyx_t_6 = (__pyx_v_signBit != 0); + __pyx_t_6 = (__pyx_v_sign_bit != 0); if (__pyx_t_6) { /* "dataRead.pyx":295 - * signBit = temp2byte & signBitMask - * if signBit: # negative value, sign extend - * temp2byte |= signExtend # <<<<<<<<<<<<<< + * sign_bit = temp2byte & sign_bit_mask + * if sign_bit: # negative value, sign extend + * temp2byte |= sign_extend # <<<<<<<<<<<<<< * buf[i] = temp2byte * return buf */ - __pyx_v_temp2byte = (__pyx_v_temp2byte | __pyx_v_signExtend); + __pyx_v_temp2byte = (__pyx_v_temp2byte | __pyx_v_sign_extend); /* "dataRead.pyx":294 * temp2byte &= mask - * signBit = temp2byte & signBitMask - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp2byte |= signExtend + * sign_bit = temp2byte & sign_bit_mask + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp2byte |= sign_extend * buf[i] = temp2byte */ } /* "dataRead.pyx":296 - * if signBit: # negative value, sign extend - * temp2byte |= signExtend + * if sign_bit: # negative value, sign extend + * temp2byte |= sign_extend * buf[i] = temp2byte # <<<<<<<<<<<<<< * return buf * @@ -5484,11 +5499,11 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadShort(char const *__pyx __pyx_L7:; /* "dataRead.pyx":297 - * temp2byte |= signExtend + * temp2byte |= sign_extend * buf[i] = temp2byte * return buf # <<<<<<<<<<<<<< * - * cdef inline dataReadUInt(const char* bita, str RecordFormat, unsigned long long numberOfRecords, + * cdef inline read_unsigned_int(const char* bit_stream, str record_format, unsigned long long number_of_records, */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject *)__pyx_v_buf)); @@ -5499,9 +5514,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadShort(char const *__pyx /* "dataRead.pyx":252 * return buf * - * cdef inline dataReadShort(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): + * cdef inline read_signed_short(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset, unsigned char swap): */ /* function exit code */ @@ -5516,7 +5531,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadShort(char const *__pyx __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_buf.rcbuffer->pybuffer); __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} - __Pyx_AddTraceback("dataRead.dataReadShort", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("dataRead.read_signed_short", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; goto __pyx_L2; __pyx_L0:; @@ -5531,12 +5546,12 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadShort(char const *__pyx /* "dataRead.pyx":299 * return buf * - * cdef inline dataReadUInt(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): + * cdef inline read_unsigned_int(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset, unsigned long n_bytes, unsigned char swap): */ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_bitCount, unsigned char __pyx_v_bitOffset, unsigned long __pyx_v_nBytes, unsigned char __pyx_v_swap) { +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_unsigned_int(char const *__pyx_v_bit_stream, PyObject *__pyx_v_record_format, unsigned PY_LONG_LONG __pyx_v_number_of_records, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_pos_byte_beg, unsigned long __pyx_v_bit_count, unsigned char __pyx_v_bit_offset, unsigned long __pyx_v_n_bytes, unsigned char __pyx_v_swap) { PyArrayObject *__pyx_v_buf = 0; unsigned PY_LONG_LONG __pyx_v_i; unsigned int __pyx_v_mask; @@ -5562,25 +5577,25 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ unsigned PY_LONG_LONG __pyx_t_13; unsigned PY_LONG_LONG __pyx_t_14; unsigned PY_LONG_LONG __pyx_t_15; - __Pyx_RefNannySetupContext("dataReadUInt", 0); + __Pyx_RefNannySetupContext("read_unsigned_int", 0); __pyx_pybuffer_buf.pybuffer.buf = NULL; __pyx_pybuffer_buf.refcount = 0; __pyx_pybuffernd_buf.data = NULL; __pyx_pybuffernd_buf.rcbuffer = &__pyx_pybuffer_buf; /* "dataRead.pyx":302 - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): - * cdef np.ndarray[np.uint32_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset, unsigned long n_bytes, unsigned char swap): + * cdef np.ndarray[np.uint32_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array # <<<<<<<<<<<<<< * cdef unsigned long long i - * cdef unsigned int mask = ((1 << bitCount) - 1) + * cdef unsigned int mask = ((1 << bit_count) - 1) */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 302, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 302, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_numberOfRecords); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 302, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_number_of_records); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 302, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 302, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); @@ -5589,7 +5604,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 302, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 302, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_record_format) < 0) __PYX_ERR(0, 302, __pyx_L1_error) __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 302, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; @@ -5610,17 +5625,17 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ __pyx_t_4 = 0; /* "dataRead.pyx":304 - * cdef np.ndarray[np.uint32_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array + * cdef np.ndarray[np.uint32_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array * cdef unsigned long long i - * cdef unsigned int mask = ((1 << bitCount) - 1) # <<<<<<<<<<<<<< + * cdef unsigned int mask = ((1 << bit_count) - 1) # <<<<<<<<<<<<<< * cdef unsigned int temp4byte = 0 * cdef char temp4[4] */ - __pyx_v_mask = ((1 << __pyx_v_bitCount) - 1); + __pyx_v_mask = ((1 << __pyx_v_bit_count) - 1); /* "dataRead.pyx":305 * cdef unsigned long long i - * cdef unsigned int mask = ((1 << bitCount) - 1) + * cdef unsigned int mask = ((1 << bit_count) - 1) * cdef unsigned int temp4byte = 0 # <<<<<<<<<<<<<< * cdef char temp4[4] * cdef char temp3[3] @@ -5630,37 +5645,37 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ /* "dataRead.pyx":308 * cdef char temp4[4] * cdef char temp3[3] - * if bitCount == 32: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) + * if bit_count == 32: # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], 4) */ - __pyx_t_6 = ((__pyx_v_bitCount == 32) != 0); + __pyx_t_6 = ((__pyx_v_bit_count == 32) != 0); if (__pyx_t_6) { /* "dataRead.pyx":309 * cdef char temp3[3] - * if bitCount == 32: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) + * if bit_count == 32: + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], 4) * buf[i] = temp4byte */ - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":310 - * if bitCount == 32: - * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) # <<<<<<<<<<<<<< + * if bit_count == 32: + * for i in range(number_of_records): + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], 4) # <<<<<<<<<<<<<< * buf[i] = temp4byte * if swap == 0: */ - (void)(memcpy((&__pyx_v_temp4byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), 4)); + (void)(memcpy((&__pyx_v_temp4byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), 4)); /* "dataRead.pyx":311 - * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) + * for i in range(number_of_records): + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], 4) * buf[i] = temp4byte # <<<<<<<<<<<<<< * if swap == 0: * return buf @@ -5676,7 +5691,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ } /* "dataRead.pyx":312 - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], 4) * buf[i] = temp4byte * if swap == 0: # <<<<<<<<<<<<<< * return buf @@ -5698,7 +5713,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ goto __pyx_L0; /* "dataRead.pyx":312 - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], 4) * buf[i] = temp4byte * if swap == 0: # <<<<<<<<<<<<<< * return buf @@ -5710,7 +5725,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ * return buf * else: * return buf.byteswap() # <<<<<<<<<<<<<< - * elif nBytes == 4: + * elif n_bytes == 4: * if swap == 0: */ /*else*/ { @@ -5743,94 +5758,94 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ /* "dataRead.pyx":308 * cdef char temp4[4] * cdef char temp3[3] - * if bitCount == 32: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) + * if bit_count == 32: # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], 4) */ } /* "dataRead.pyx":316 * else: * return buf.byteswap() - * elif nBytes == 4: # <<<<<<<<<<<<<< + * elif n_bytes == 4: # <<<<<<<<<<<<<< * if swap == 0: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ - __pyx_t_6 = ((__pyx_v_nBytes == 4) != 0); + __pyx_t_6 = ((__pyx_v_n_bytes == 4) != 0); if (__pyx_t_6) { /* "dataRead.pyx":317 * return buf.byteswap() - * elif nBytes == 4: + * elif n_bytes == 4: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":318 - * elif nBytes == 4: + * elif n_bytes == 4: * if swap == 0: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift */ - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":319 * if swap == 0: - * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ - (void)(memcpy((&__pyx_v_temp4byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp4byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":321 - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp4byte = temp4byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp4byte = temp4byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":322 * # right shift - * if bitOffset > 0: - * temp4byte = temp4byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp4byte = temp4byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 32: + * if bit_count < 32: */ - __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bitOffset); + __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bit_offset); /* "dataRead.pyx":321 - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp4byte = temp4byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp4byte = temp4byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":324 - * temp4byte = temp4byte >> bitOffset + * temp4byte = temp4byte >> bit_offset * # mask left part - * if bitCount < 32: # <<<<<<<<<<<<<< + * if bit_count < 32: # <<<<<<<<<<<<<< * temp4byte &= mask * buf[i] = temp4byte */ - __pyx_t_6 = ((__pyx_v_bitCount < 32) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 32) != 0); if (__pyx_t_6) { /* "dataRead.pyx":325 * # mask left part - * if bitCount < 32: + * if bit_count < 32: * temp4byte &= mask # <<<<<<<<<<<<<< * buf[i] = temp4byte * else: @@ -5838,20 +5853,20 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ __pyx_v_temp4byte = (__pyx_v_temp4byte & __pyx_v_mask); /* "dataRead.pyx":324 - * temp4byte = temp4byte >> bitOffset + * temp4byte = temp4byte >> bit_offset * # mask left part - * if bitCount < 32: # <<<<<<<<<<<<<< + * if bit_count < 32: # <<<<<<<<<<<<<< * temp4byte &= mask * buf[i] = temp4byte */ } /* "dataRead.pyx":326 - * if bitCount < 32: + * if bit_count < 32: * temp4byte &= mask * buf[i] = temp4byte # <<<<<<<<<<<<<< * else: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ __pyx_t_12 = __pyx_v_i; __pyx_t_11 = -1; @@ -5865,10 +5880,10 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ /* "dataRead.pyx":317 * return buf.byteswap() - * elif nBytes == 4: + * elif n_bytes == 4: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ goto __pyx_L7; } @@ -5876,75 +5891,75 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ /* "dataRead.pyx":328 * buf[i] = temp4byte * else: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp4, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp4, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp4byte = temp4[0]<<24 | temp4[1]<<16 | temp4[2]<<8 | temp4[3] # swap bytes */ /*else*/ { - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":329 * else: - * for i in range(numberOfRecords): - * memcpy(&temp4, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp4, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * temp4byte = temp4[0]<<24 | temp4[1]<<16 | temp4[2]<<8 | temp4[3] # swap bytes * # right shift */ - (void)(memcpy((&__pyx_v_temp4), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp4), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":330 - * for i in range(numberOfRecords): - * memcpy(&temp4, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp4, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp4byte = temp4[0]<<24 | temp4[1]<<16 | temp4[2]<<8 | temp4[3] # swap bytes # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ __pyx_v_temp4byte = (((((__pyx_v_temp4[0]) << 24) | ((__pyx_v_temp4[1]) << 16)) | ((__pyx_v_temp4[2]) << 8)) | (__pyx_v_temp4[3])); /* "dataRead.pyx":332 * temp4byte = temp4[0]<<24 | temp4[1]<<16 | temp4[2]<<8 | temp4[3] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp4byte = temp4byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp4byte = temp4byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":333 * # right shift - * if bitOffset > 0: - * temp4byte = temp4byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp4byte = temp4byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 32: + * if bit_count < 32: */ - __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bitOffset); + __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bit_offset); /* "dataRead.pyx":332 * temp4byte = temp4[0]<<24 | temp4[1]<<16 | temp4[2]<<8 | temp4[3] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp4byte = temp4byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp4byte = temp4byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":335 - * temp4byte = temp4byte >> bitOffset + * temp4byte = temp4byte >> bit_offset * # mask left part - * if bitCount < 32: # <<<<<<<<<<<<<< + * if bit_count < 32: # <<<<<<<<<<<<<< * temp4byte &= mask * buf[i] = temp4byte */ - __pyx_t_6 = ((__pyx_v_bitCount < 32) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 32) != 0); if (__pyx_t_6) { /* "dataRead.pyx":336 * # mask left part - * if bitCount < 32: + * if bit_count < 32: * temp4byte &= mask # <<<<<<<<<<<<<< * buf[i] = temp4byte * return buf @@ -5952,16 +5967,16 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ __pyx_v_temp4byte = (__pyx_v_temp4byte & __pyx_v_mask); /* "dataRead.pyx":335 - * temp4byte = temp4byte >> bitOffset + * temp4byte = temp4byte >> bit_offset * # mask left part - * if bitCount < 32: # <<<<<<<<<<<<<< + * if bit_count < 32: # <<<<<<<<<<<<<< * temp4byte &= mask * buf[i] = temp4byte */ } /* "dataRead.pyx":337 - * if bitCount < 32: + * if bit_count < 32: * temp4byte &= mask * buf[i] = temp4byte # <<<<<<<<<<<<<< * return buf @@ -5994,9 +6009,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ /* "dataRead.pyx":316 * else: * return buf.byteswap() - * elif nBytes == 4: # <<<<<<<<<<<<<< + * elif n_bytes == 4: # <<<<<<<<<<<<<< * if swap == 0: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ } @@ -6004,8 +6019,8 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ * return buf * else: # on 3 bytes * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ /*else*/ { __pyx_t_6 = ((__pyx_v_swap == 0) != 0); @@ -6014,65 +6029,65 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ /* "dataRead.pyx":341 * else: # on 3 bytes * if swap == 0: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift */ - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":342 * if swap == 0: - * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ - (void)(memcpy((&__pyx_v_temp4byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp4byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":344 - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp4byte = temp4byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp4byte = temp4byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":345 * # right shift - * if bitOffset > 0: - * temp4byte = temp4byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp4byte = temp4byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 24: + * if bit_count < 24: */ - __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bitOffset); + __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bit_offset); /* "dataRead.pyx":344 - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp4byte = temp4byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp4byte = temp4byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":347 - * temp4byte = temp4byte >> bitOffset + * temp4byte = temp4byte >> bit_offset * # mask left part - * if bitCount < 24: # <<<<<<<<<<<<<< + * if bit_count < 24: # <<<<<<<<<<<<<< * temp4byte &= mask * buf[i] = temp4byte */ - __pyx_t_6 = ((__pyx_v_bitCount < 24) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 24) != 0); if (__pyx_t_6) { /* "dataRead.pyx":348 * # mask left part - * if bitCount < 24: + * if bit_count < 24: * temp4byte &= mask # <<<<<<<<<<<<<< * buf[i] = temp4byte * else: @@ -6080,20 +6095,20 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ __pyx_v_temp4byte = (__pyx_v_temp4byte & __pyx_v_mask); /* "dataRead.pyx":347 - * temp4byte = temp4byte >> bitOffset + * temp4byte = temp4byte >> bit_offset * # mask left part - * if bitCount < 24: # <<<<<<<<<<<<<< + * if bit_count < 24: # <<<<<<<<<<<<<< * temp4byte &= mask * buf[i] = temp4byte */ } /* "dataRead.pyx":349 - * if bitCount < 24: + * if bit_count < 24: * temp4byte &= mask * buf[i] = temp4byte # <<<<<<<<<<<<<< * else: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ __pyx_t_14 = __pyx_v_i; __pyx_t_11 = -1; @@ -6109,8 +6124,8 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ * return buf * else: # on 3 bytes * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ goto __pyx_L16; } @@ -6118,75 +6133,75 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ /* "dataRead.pyx":351 * buf[i] = temp4byte * else: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp3, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp3, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp4byte = temp3[0]<<16 | temp3[1]<<8 | temp3[2] # swap bytes */ /*else*/ { - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":352 * else: - * for i in range(numberOfRecords): - * memcpy(&temp3, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp3, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * temp4byte = temp3[0]<<16 | temp3[1]<<8 | temp3[2] # swap bytes * # right shift */ - (void)(memcpy((&__pyx_v_temp3), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp3), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":353 - * for i in range(numberOfRecords): - * memcpy(&temp3, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp3, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp4byte = temp3[0]<<16 | temp3[1]<<8 | temp3[2] # swap bytes # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ __pyx_v_temp4byte = ((((__pyx_v_temp3[0]) << 16) | ((__pyx_v_temp3[1]) << 8)) | (__pyx_v_temp3[2])); /* "dataRead.pyx":355 * temp4byte = temp3[0]<<16 | temp3[1]<<8 | temp3[2] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp4byte = temp4byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp4byte = temp4byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":356 * # right shift - * if bitOffset > 0: - * temp4byte = temp4byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp4byte = temp4byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 24: + * if bit_count < 24: */ - __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bitOffset); + __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bit_offset); /* "dataRead.pyx":355 * temp4byte = temp3[0]<<16 | temp3[1]<<8 | temp3[2] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp4byte = temp4byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp4byte = temp4byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":358 - * temp4byte = temp4byte >> bitOffset + * temp4byte = temp4byte >> bit_offset * # mask left part - * if bitCount < 24: # <<<<<<<<<<<<<< + * if bit_count < 24: # <<<<<<<<<<<<<< * temp4byte &= mask * buf[i] = temp4byte */ - __pyx_t_6 = ((__pyx_v_bitCount < 24) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 24) != 0); if (__pyx_t_6) { /* "dataRead.pyx":359 * # mask left part - * if bitCount < 24: + * if bit_count < 24: * temp4byte &= mask # <<<<<<<<<<<<<< * buf[i] = temp4byte * return buf @@ -6194,16 +6209,16 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ __pyx_v_temp4byte = (__pyx_v_temp4byte & __pyx_v_mask); /* "dataRead.pyx":358 - * temp4byte = temp4byte >> bitOffset + * temp4byte = temp4byte >> bit_offset * # mask left part - * if bitCount < 24: # <<<<<<<<<<<<<< + * if bit_count < 24: # <<<<<<<<<<<<<< * temp4byte &= mask * buf[i] = temp4byte */ } /* "dataRead.pyx":360 - * if bitCount < 24: + * if bit_count < 24: * temp4byte &= mask * buf[i] = temp4byte # <<<<<<<<<<<<<< * return buf @@ -6237,9 +6252,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ /* "dataRead.pyx":299 * return buf * - * cdef inline dataReadUInt(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): + * cdef inline read_unsigned_int(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset, unsigned long n_bytes, unsigned char swap): */ /* function exit code */ @@ -6254,7 +6269,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_buf.rcbuffer->pybuffer); __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} - __Pyx_AddTraceback("dataRead.dataReadUInt", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("dataRead.read_unsigned_int", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; goto __pyx_L2; __pyx_L0:; @@ -6269,19 +6284,19 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadUInt(char const *__pyx_ /* "dataRead.pyx":364 * * - * cdef inline dataReadInt(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): + * cdef inline read_signed_int(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset, unsigned long n_bytes, unsigned char swap): */ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_bitCount, unsigned char __pyx_v_bitOffset, unsigned long __pyx_v_nBytes, unsigned char __pyx_v_swap) { +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_signed_int(char const *__pyx_v_bit_stream, PyObject *__pyx_v_record_format, unsigned PY_LONG_LONG __pyx_v_number_of_records, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_pos_byte_beg, unsigned long __pyx_v_bit_count, unsigned char __pyx_v_bit_offset, unsigned long __pyx_v_n_bytes, unsigned char __pyx_v_swap) { PyArrayObject *__pyx_v_buf = 0; unsigned PY_LONG_LONG __pyx_v_i; int __pyx_v_mask; int __pyx_v_temp4byte; - int __pyx_v_signBit; - int __pyx_v_signBitMask; - int __pyx_v_signExtend; + int __pyx_v_sign_bit; + int __pyx_v_sign_bit_mask; + int __pyx_v_sign_extend; char __pyx_v_temp4[4]; char __pyx_v_temp3[3]; __Pyx_LocalBuf_ND __pyx_pybuffernd_buf; @@ -6303,25 +6318,25 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v unsigned PY_LONG_LONG __pyx_t_13; unsigned PY_LONG_LONG __pyx_t_14; unsigned PY_LONG_LONG __pyx_t_15; - __Pyx_RefNannySetupContext("dataReadInt", 0); + __Pyx_RefNannySetupContext("read_signed_int", 0); __pyx_pybuffer_buf.pybuffer.buf = NULL; __pyx_pybuffer_buf.refcount = 0; __pyx_pybuffernd_buf.data = NULL; __pyx_pybuffernd_buf.rcbuffer = &__pyx_pybuffer_buf; /* "dataRead.pyx":367 - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): - * cdef np.ndarray[np.int32_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset, unsigned long n_bytes, unsigned char swap): + * cdef np.ndarray[np.int32_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array # <<<<<<<<<<<<<< * cdef unsigned long long i - * cdef int mask = ((1 << bitCount) - 1) + * cdef int mask = ((1 << bit_count) - 1) */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 367, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 367, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_numberOfRecords); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 367, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_number_of_records); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 367, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 367, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); @@ -6330,7 +6345,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 367, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 367, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_record_format) < 0) __PYX_ERR(0, 367, __pyx_L1_error) __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 367, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; @@ -6351,84 +6366,84 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_t_4 = 0; /* "dataRead.pyx":369 - * cdef np.ndarray[np.int32_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array + * cdef np.ndarray[np.int32_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array * cdef unsigned long long i - * cdef int mask = ((1 << bitCount) - 1) # <<<<<<<<<<<<<< + * cdef int mask = ((1 << bit_count) - 1) # <<<<<<<<<<<<<< * cdef int temp4byte = 0 - * cdef int signBit = 0 + * cdef int sign_bit = 0 */ - __pyx_v_mask = ((1 << __pyx_v_bitCount) - 1); + __pyx_v_mask = ((1 << __pyx_v_bit_count) - 1); /* "dataRead.pyx":370 * cdef unsigned long long i - * cdef int mask = ((1 << bitCount) - 1) + * cdef int mask = ((1 << bit_count) - 1) * cdef int temp4byte = 0 # <<<<<<<<<<<<<< - * cdef int signBit = 0 - * cdef int signBitMask = (1 << (bitCount-1)) + * cdef int sign_bit = 0 + * cdef int sign_bit_mask = (1 << (bit_count-1)) */ __pyx_v_temp4byte = 0; /* "dataRead.pyx":371 - * cdef int mask = ((1 << bitCount) - 1) + * cdef int mask = ((1 << bit_count) - 1) * cdef int temp4byte = 0 - * cdef int signBit = 0 # <<<<<<<<<<<<<< - * cdef int signBitMask = (1 << (bitCount-1)) - * cdef int signExtend = ((1 << (32 - bitCount)) - 1) << bitCount + * cdef int sign_bit = 0 # <<<<<<<<<<<<<< + * cdef int sign_bit_mask = (1 << (bit_count-1)) + * cdef int sign_extend = ((1 << (32 - bit_count)) - 1) << bit_count */ - __pyx_v_signBit = 0; + __pyx_v_sign_bit = 0; /* "dataRead.pyx":372 * cdef int temp4byte = 0 - * cdef int signBit = 0 - * cdef int signBitMask = (1 << (bitCount-1)) # <<<<<<<<<<<<<< - * cdef int signExtend = ((1 << (32 - bitCount)) - 1) << bitCount + * cdef int sign_bit = 0 + * cdef int sign_bit_mask = (1 << (bit_count-1)) # <<<<<<<<<<<<<< + * cdef int sign_extend = ((1 << (32 - bit_count)) - 1) << bit_count * cdef char temp4[4] */ - __pyx_v_signBitMask = (1 << (__pyx_v_bitCount - 1)); + __pyx_v_sign_bit_mask = (1 << (__pyx_v_bit_count - 1)); /* "dataRead.pyx":373 - * cdef int signBit = 0 - * cdef int signBitMask = (1 << (bitCount-1)) - * cdef int signExtend = ((1 << (32 - bitCount)) - 1) << bitCount # <<<<<<<<<<<<<< + * cdef int sign_bit = 0 + * cdef int sign_bit_mask = (1 << (bit_count-1)) + * cdef int sign_extend = ((1 << (32 - bit_count)) - 1) << bit_count # <<<<<<<<<<<<<< * cdef char temp4[4] * cdef char temp3[3] */ - __pyx_v_signExtend = (((1 << (32 - __pyx_v_bitCount)) - 1) << __pyx_v_bitCount); + __pyx_v_sign_extend = (((1 << (32 - __pyx_v_bit_count)) - 1) << __pyx_v_bit_count); /* "dataRead.pyx":376 * cdef char temp4[4] * cdef char temp3[3] - * if bitCount == 32: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) + * if bit_count == 32: # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], 4) */ - __pyx_t_6 = ((__pyx_v_bitCount == 32) != 0); + __pyx_t_6 = ((__pyx_v_bit_count == 32) != 0); if (__pyx_t_6) { /* "dataRead.pyx":377 * cdef char temp3[3] - * if bitCount == 32: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) + * if bit_count == 32: + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], 4) * buf[i] = temp4byte */ - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":378 - * if bitCount == 32: - * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) # <<<<<<<<<<<<<< + * if bit_count == 32: + * for i in range(number_of_records): + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], 4) # <<<<<<<<<<<<<< * buf[i] = temp4byte * if swap == 0: */ - (void)(memcpy((&__pyx_v_temp4byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), 4)); + (void)(memcpy((&__pyx_v_temp4byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), 4)); /* "dataRead.pyx":379 - * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) + * for i in range(number_of_records): + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], 4) * buf[i] = temp4byte # <<<<<<<<<<<<<< * if swap == 0: * return buf @@ -6444,7 +6459,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v } /* "dataRead.pyx":380 - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], 4) * buf[i] = temp4byte * if swap == 0: # <<<<<<<<<<<<<< * return buf @@ -6466,7 +6481,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v goto __pyx_L0; /* "dataRead.pyx":380 - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], 4) * buf[i] = temp4byte * if swap == 0: # <<<<<<<<<<<<<< * return buf @@ -6478,7 +6493,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v * return buf * else: * return buf.byteswap() # <<<<<<<<<<<<<< - * elif nBytes == 4: + * elif n_bytes == 4: * if swap == 0: */ /*else*/ { @@ -6511,152 +6526,152 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v /* "dataRead.pyx":376 * cdef char temp4[4] * cdef char temp3[3] - * if bitCount == 32: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], 4) + * if bit_count == 32: # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], 4) */ } /* "dataRead.pyx":384 * else: * return buf.byteswap() - * elif nBytes == 4: # <<<<<<<<<<<<<< + * elif n_bytes == 4: # <<<<<<<<<<<<<< * if swap == 0: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ - __pyx_t_6 = ((__pyx_v_nBytes == 4) != 0); + __pyx_t_6 = ((__pyx_v_n_bytes == 4) != 0); if (__pyx_t_6) { /* "dataRead.pyx":385 * return buf.byteswap() - * elif nBytes == 4: + * elif n_bytes == 4: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":386 - * elif nBytes == 4: + * elif n_bytes == 4: * if swap == 0: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift */ - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":387 * if swap == 0: - * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ - (void)(memcpy((&__pyx_v_temp4byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp4byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":389 - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp4byte = temp4byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp4byte = temp4byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":390 * # right shift - * if bitOffset > 0: - * temp4byte = temp4byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp4byte = temp4byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 32: + * if bit_count < 32: */ - __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bitOffset); + __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bit_offset); /* "dataRead.pyx":389 - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp4byte = temp4byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp4byte = temp4byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":392 - * temp4byte = temp4byte >> bitOffset + * temp4byte = temp4byte >> bit_offset * # mask left part - * if bitCount < 32: # <<<<<<<<<<<<<< + * if bit_count < 32: # <<<<<<<<<<<<<< * temp4byte &= mask - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed */ - __pyx_t_6 = ((__pyx_v_bitCount < 32) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 32) != 0); if (__pyx_t_6) { /* "dataRead.pyx":393 * # mask left part - * if bitCount < 32: + * if bit_count < 32: * temp4byte &= mask # <<<<<<<<<<<<<< - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed - * if signBit: # negative value, sign extend + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed + * if sign_bit: # negative value, sign extend */ __pyx_v_temp4byte = (__pyx_v_temp4byte & __pyx_v_mask); /* "dataRead.pyx":392 - * temp4byte = temp4byte >> bitOffset + * temp4byte = temp4byte >> bit_offset * # mask left part - * if bitCount < 32: # <<<<<<<<<<<<<< + * if bit_count < 32: # <<<<<<<<<<<<<< * temp4byte &= mask - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed */ } /* "dataRead.pyx":394 - * if bitCount < 32: + * if bit_count < 32: * temp4byte &= mask - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed # <<<<<<<<<<<<<< - * if signBit: # negative value, sign extend - * temp4byte |= signExtend + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed # <<<<<<<<<<<<<< + * if sign_bit: # negative value, sign extend + * temp4byte |= sign_extend */ - __pyx_v_signBit = (__pyx_v_temp4byte & __pyx_v_signBitMask); + __pyx_v_sign_bit = (__pyx_v_temp4byte & __pyx_v_sign_bit_mask); /* "dataRead.pyx":395 * temp4byte &= mask - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp4byte |= signExtend + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp4byte |= sign_extend * buf[i] = temp4byte */ - __pyx_t_6 = (__pyx_v_signBit != 0); + __pyx_t_6 = (__pyx_v_sign_bit != 0); if (__pyx_t_6) { /* "dataRead.pyx":396 - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed - * if signBit: # negative value, sign extend - * temp4byte |= signExtend # <<<<<<<<<<<<<< + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed + * if sign_bit: # negative value, sign extend + * temp4byte |= sign_extend # <<<<<<<<<<<<<< * buf[i] = temp4byte * else: */ - __pyx_v_temp4byte = (__pyx_v_temp4byte | __pyx_v_signExtend); + __pyx_v_temp4byte = (__pyx_v_temp4byte | __pyx_v_sign_extend); /* "dataRead.pyx":395 * temp4byte &= mask - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp4byte |= signExtend + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp4byte |= sign_extend * buf[i] = temp4byte */ } /* "dataRead.pyx":397 - * if signBit: # negative value, sign extend - * temp4byte |= signExtend + * if sign_bit: # negative value, sign extend + * temp4byte |= sign_extend * buf[i] = temp4byte # <<<<<<<<<<<<<< * else: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ __pyx_t_12 = __pyx_v_i; __pyx_t_11 = -1; @@ -6670,10 +6685,10 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v /* "dataRead.pyx":385 * return buf.byteswap() - * elif nBytes == 4: + * elif n_bytes == 4: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ goto __pyx_L7; } @@ -6681,130 +6696,130 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v /* "dataRead.pyx":399 * buf[i] = temp4byte * else: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp4, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp4, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp4byte = temp4[0]<<24 | temp4[1]<<16 | temp4[2]<<8 | temp4[3] # swap bytes */ /*else*/ { - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":400 * else: - * for i in range(numberOfRecords): - * memcpy(&temp4, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp4, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * temp4byte = temp4[0]<<24 | temp4[1]<<16 | temp4[2]<<8 | temp4[3] # swap bytes * # right shift */ - (void)(memcpy((&__pyx_v_temp4), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp4), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":401 - * for i in range(numberOfRecords): - * memcpy(&temp4, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp4, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp4byte = temp4[0]<<24 | temp4[1]<<16 | temp4[2]<<8 | temp4[3] # swap bytes # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ __pyx_v_temp4byte = (((((__pyx_v_temp4[0]) << 24) | ((__pyx_v_temp4[1]) << 16)) | ((__pyx_v_temp4[2]) << 8)) | (__pyx_v_temp4[3])); /* "dataRead.pyx":403 * temp4byte = temp4[0]<<24 | temp4[1]<<16 | temp4[2]<<8 | temp4[3] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp4byte = temp4byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp4byte = temp4byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":404 * # right shift - * if bitOffset > 0: - * temp4byte = temp4byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp4byte = temp4byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 32: + * if bit_count < 32: */ - __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bitOffset); + __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bit_offset); /* "dataRead.pyx":403 * temp4byte = temp4[0]<<24 | temp4[1]<<16 | temp4[2]<<8 | temp4[3] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp4byte = temp4byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp4byte = temp4byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":406 - * temp4byte = temp4byte >> bitOffset + * temp4byte = temp4byte >> bit_offset * # mask left part - * if bitCount < 32: # <<<<<<<<<<<<<< + * if bit_count < 32: # <<<<<<<<<<<<<< * temp4byte &= mask - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed */ - __pyx_t_6 = ((__pyx_v_bitCount < 32) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 32) != 0); if (__pyx_t_6) { /* "dataRead.pyx":407 * # mask left part - * if bitCount < 32: + * if bit_count < 32: * temp4byte &= mask # <<<<<<<<<<<<<< - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed - * if signBit: # negative value, sign extend + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed + * if sign_bit: # negative value, sign extend */ __pyx_v_temp4byte = (__pyx_v_temp4byte & __pyx_v_mask); /* "dataRead.pyx":406 - * temp4byte = temp4byte >> bitOffset + * temp4byte = temp4byte >> bit_offset * # mask left part - * if bitCount < 32: # <<<<<<<<<<<<<< + * if bit_count < 32: # <<<<<<<<<<<<<< * temp4byte &= mask - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed */ } /* "dataRead.pyx":408 - * if bitCount < 32: + * if bit_count < 32: * temp4byte &= mask - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed # <<<<<<<<<<<<<< - * if signBit: # negative value, sign extend - * temp4byte |= signExtend + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed # <<<<<<<<<<<<<< + * if sign_bit: # negative value, sign extend + * temp4byte |= sign_extend */ - __pyx_v_signBit = (__pyx_v_temp4byte & __pyx_v_signBitMask); + __pyx_v_sign_bit = (__pyx_v_temp4byte & __pyx_v_sign_bit_mask); /* "dataRead.pyx":409 * temp4byte &= mask - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp4byte |= signExtend + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp4byte |= sign_extend * buf[i] = temp4byte */ - __pyx_t_6 = (__pyx_v_signBit != 0); + __pyx_t_6 = (__pyx_v_sign_bit != 0); if (__pyx_t_6) { /* "dataRead.pyx":410 - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed - * if signBit: # negative value, sign extend - * temp4byte |= signExtend # <<<<<<<<<<<<<< + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed + * if sign_bit: # negative value, sign extend + * temp4byte |= sign_extend # <<<<<<<<<<<<<< * buf[i] = temp4byte * return buf */ - __pyx_v_temp4byte = (__pyx_v_temp4byte | __pyx_v_signExtend); + __pyx_v_temp4byte = (__pyx_v_temp4byte | __pyx_v_sign_extend); /* "dataRead.pyx":409 * temp4byte &= mask - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp4byte |= signExtend + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp4byte |= sign_extend * buf[i] = temp4byte */ } /* "dataRead.pyx":411 - * if signBit: # negative value, sign extend - * temp4byte |= signExtend + * if sign_bit: # negative value, sign extend + * temp4byte |= sign_extend * buf[i] = temp4byte # <<<<<<<<<<<<<< * return buf * else: # on 3 bytes @@ -6822,7 +6837,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_L7:; /* "dataRead.pyx":412 - * temp4byte |= signExtend + * temp4byte |= sign_extend * buf[i] = temp4byte * return buf # <<<<<<<<<<<<<< * else: # on 3 bytes @@ -6836,9 +6851,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v /* "dataRead.pyx":384 * else: * return buf.byteswap() - * elif nBytes == 4: # <<<<<<<<<<<<<< + * elif n_bytes == 4: # <<<<<<<<<<<<<< * if swap == 0: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ } @@ -6846,8 +6861,8 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v * return buf * else: # on 3 bytes * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ /*else*/ { __pyx_t_6 = ((__pyx_v_swap == 0) != 0); @@ -6856,123 +6871,123 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v /* "dataRead.pyx":415 * else: # on 3 bytes * if swap == 0: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift */ - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":416 * if swap == 0: - * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ - (void)(memcpy((&__pyx_v_temp4byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp4byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":418 - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp4byte = temp4byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp4byte = temp4byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":419 * # right shift - * if bitOffset > 0: - * temp4byte = temp4byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp4byte = temp4byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 24: + * if bit_count < 24: */ - __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bitOffset); + __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bit_offset); /* "dataRead.pyx":418 - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp4byte = temp4byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp4byte = temp4byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":421 - * temp4byte = temp4byte >> bitOffset + * temp4byte = temp4byte >> bit_offset * # mask left part - * if bitCount < 24: # <<<<<<<<<<<<<< + * if bit_count < 24: # <<<<<<<<<<<<<< * temp4byte &= mask - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed */ - __pyx_t_6 = ((__pyx_v_bitCount < 24) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 24) != 0); if (__pyx_t_6) { /* "dataRead.pyx":422 * # mask left part - * if bitCount < 24: + * if bit_count < 24: * temp4byte &= mask # <<<<<<<<<<<<<< - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed - * if signBit: # negative value, sign extend + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed + * if sign_bit: # negative value, sign extend */ __pyx_v_temp4byte = (__pyx_v_temp4byte & __pyx_v_mask); /* "dataRead.pyx":421 - * temp4byte = temp4byte >> bitOffset + * temp4byte = temp4byte >> bit_offset * # mask left part - * if bitCount < 24: # <<<<<<<<<<<<<< + * if bit_count < 24: # <<<<<<<<<<<<<< * temp4byte &= mask - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed */ } /* "dataRead.pyx":423 - * if bitCount < 24: + * if bit_count < 24: * temp4byte &= mask - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed # <<<<<<<<<<<<<< - * if signBit: # negative value, sign extend - * temp4byte |= signExtend + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed # <<<<<<<<<<<<<< + * if sign_bit: # negative value, sign extend + * temp4byte |= sign_extend */ - __pyx_v_signBit = (__pyx_v_temp4byte & __pyx_v_signBitMask); + __pyx_v_sign_bit = (__pyx_v_temp4byte & __pyx_v_sign_bit_mask); /* "dataRead.pyx":424 * temp4byte &= mask - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp4byte |= signExtend + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp4byte |= sign_extend * buf[i] = temp4byte */ - __pyx_t_6 = (__pyx_v_signBit != 0); + __pyx_t_6 = (__pyx_v_sign_bit != 0); if (__pyx_t_6) { /* "dataRead.pyx":425 - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed - * if signBit: # negative value, sign extend - * temp4byte |= signExtend # <<<<<<<<<<<<<< + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed + * if sign_bit: # negative value, sign extend + * temp4byte |= sign_extend # <<<<<<<<<<<<<< * buf[i] = temp4byte * else: */ - __pyx_v_temp4byte = (__pyx_v_temp4byte | __pyx_v_signExtend); + __pyx_v_temp4byte = (__pyx_v_temp4byte | __pyx_v_sign_extend); /* "dataRead.pyx":424 * temp4byte &= mask - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp4byte |= signExtend + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp4byte |= sign_extend * buf[i] = temp4byte */ } /* "dataRead.pyx":426 - * if signBit: # negative value, sign extend - * temp4byte |= signExtend + * if sign_bit: # negative value, sign extend + * temp4byte |= sign_extend * buf[i] = temp4byte # <<<<<<<<<<<<<< * else: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ __pyx_t_14 = __pyx_v_i; __pyx_t_11 = -1; @@ -6988,8 +7003,8 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v * return buf * else: # on 3 bytes * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp4byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp4byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ goto __pyx_L18; } @@ -6997,130 +7012,130 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v /* "dataRead.pyx":428 * buf[i] = temp4byte * else: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp3, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp3, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp4byte = temp3[0]<<16 | temp3[1]<<8 | temp3[2] # swap bytes */ /*else*/ { - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":429 * else: - * for i in range(numberOfRecords): - * memcpy(&temp3, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp3, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * temp4byte = temp3[0]<<16 | temp3[1]<<8 | temp3[2] # swap bytes * # right shift */ - (void)(memcpy((&__pyx_v_temp3), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp3), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":430 - * for i in range(numberOfRecords): - * memcpy(&temp3, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp3, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp4byte = temp3[0]<<16 | temp3[1]<<8 | temp3[2] # swap bytes # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ __pyx_v_temp4byte = ((((__pyx_v_temp3[0]) << 16) | ((__pyx_v_temp3[1]) << 8)) | (__pyx_v_temp3[2])); /* "dataRead.pyx":432 * temp4byte = temp3[0]<<16 | temp3[1]<<8 | temp3[2] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp4byte = temp4byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp4byte = temp4byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":433 * # right shift - * if bitOffset > 0: - * temp4byte = temp4byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp4byte = temp4byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 24: + * if bit_count < 24: */ - __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bitOffset); + __pyx_v_temp4byte = (__pyx_v_temp4byte >> __pyx_v_bit_offset); /* "dataRead.pyx":432 * temp4byte = temp3[0]<<16 | temp3[1]<<8 | temp3[2] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp4byte = temp4byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp4byte = temp4byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":435 - * temp4byte = temp4byte >> bitOffset + * temp4byte = temp4byte >> bit_offset * # mask left part - * if bitCount < 24: # <<<<<<<<<<<<<< + * if bit_count < 24: # <<<<<<<<<<<<<< * temp4byte &= mask - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed */ - __pyx_t_6 = ((__pyx_v_bitCount < 24) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 24) != 0); if (__pyx_t_6) { /* "dataRead.pyx":436 * # mask left part - * if bitCount < 24: + * if bit_count < 24: * temp4byte &= mask # <<<<<<<<<<<<<< - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed - * if signBit: # negative value, sign extend + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed + * if sign_bit: # negative value, sign extend */ __pyx_v_temp4byte = (__pyx_v_temp4byte & __pyx_v_mask); /* "dataRead.pyx":435 - * temp4byte = temp4byte >> bitOffset + * temp4byte = temp4byte >> bit_offset * # mask left part - * if bitCount < 24: # <<<<<<<<<<<<<< + * if bit_count < 24: # <<<<<<<<<<<<<< * temp4byte &= mask - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed */ } /* "dataRead.pyx":437 - * if bitCount < 24: + * if bit_count < 24: * temp4byte &= mask - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed # <<<<<<<<<<<<<< - * if signBit: # negative value, sign extend - * temp4byte |= signExtend + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed # <<<<<<<<<<<<<< + * if sign_bit: # negative value, sign extend + * temp4byte |= sign_extend */ - __pyx_v_signBit = (__pyx_v_temp4byte & __pyx_v_signBitMask); + __pyx_v_sign_bit = (__pyx_v_temp4byte & __pyx_v_sign_bit_mask); /* "dataRead.pyx":438 * temp4byte &= mask - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp4byte |= signExtend + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp4byte |= sign_extend * buf[i] = temp4byte */ - __pyx_t_6 = (__pyx_v_signBit != 0); + __pyx_t_6 = (__pyx_v_sign_bit != 0); if (__pyx_t_6) { /* "dataRead.pyx":439 - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed - * if signBit: # negative value, sign extend - * temp4byte |= signExtend # <<<<<<<<<<<<<< + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed + * if sign_bit: # negative value, sign extend + * temp4byte |= sign_extend # <<<<<<<<<<<<<< * buf[i] = temp4byte * return buf */ - __pyx_v_temp4byte = (__pyx_v_temp4byte | __pyx_v_signExtend); + __pyx_v_temp4byte = (__pyx_v_temp4byte | __pyx_v_sign_extend); /* "dataRead.pyx":438 * temp4byte &= mask - * signBit = temp4byte & signBitMask # assumes return in little endian, to be reviewed - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp4byte |= signExtend + * sign_bit = temp4byte & sign_bit_mask # assumes return in little endian, to be reviewed + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp4byte |= sign_extend * buf[i] = temp4byte */ } /* "dataRead.pyx":440 - * if signBit: # negative value, sign extend - * temp4byte |= signExtend + * if sign_bit: # negative value, sign extend + * temp4byte |= sign_extend * buf[i] = temp4byte # <<<<<<<<<<<<<< * return buf * @@ -7138,11 +7153,11 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __pyx_L18:; /* "dataRead.pyx":441 - * temp4byte |= signExtend + * temp4byte |= sign_extend * buf[i] = temp4byte * return buf # <<<<<<<<<<<<<< * - * cdef inline dataReadULongLong(const char* bita, str RecordFormat, unsigned long long numberOfRecords, + * cdef inline read_unsigned_longlong(const char* bit_stream, str record_format, unsigned long long number_of_records, */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject *)__pyx_v_buf)); @@ -7153,9 +7168,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v /* "dataRead.pyx":364 * * - * cdef inline dataReadInt(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): + * cdef inline read_signed_int(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset, unsigned long n_bytes, unsigned char swap): */ /* function exit code */ @@ -7170,7 +7185,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_buf.rcbuffer->pybuffer); __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} - __Pyx_AddTraceback("dataRead.dataReadInt", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("dataRead.read_signed_int", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; goto __pyx_L2; __pyx_L0:; @@ -7185,12 +7200,12 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadInt(char const *__pyx_v /* "dataRead.pyx":443 * return buf * - * cdef inline dataReadULongLong(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): + * cdef inline read_unsigned_longlong(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset, unsigned long n_bytes, unsigned char swap): */ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_bitCount, unsigned char __pyx_v_bitOffset, unsigned long __pyx_v_nBytes, unsigned char __pyx_v_swap) { +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_unsigned_longlong(char const *__pyx_v_bit_stream, PyObject *__pyx_v_record_format, unsigned PY_LONG_LONG __pyx_v_number_of_records, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_pos_byte_beg, unsigned long __pyx_v_bit_count, unsigned char __pyx_v_bit_offset, unsigned long __pyx_v_n_bytes, unsigned char __pyx_v_swap) { PyArrayObject *__pyx_v_buf = 0; unsigned PY_LONG_LONG __pyx_v_i; unsigned PY_LONG_LONG __pyx_v_mask; @@ -7222,25 +7237,25 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ unsigned PY_LONG_LONG __pyx_t_17; unsigned PY_LONG_LONG __pyx_t_18; unsigned PY_LONG_LONG __pyx_t_19; - __Pyx_RefNannySetupContext("dataReadULongLong", 0); + __Pyx_RefNannySetupContext("read_unsigned_longlong", 0); __pyx_pybuffer_buf.pybuffer.buf = NULL; __pyx_pybuffer_buf.refcount = 0; __pyx_pybuffernd_buf.data = NULL; __pyx_pybuffernd_buf.rcbuffer = &__pyx_pybuffer_buf; /* "dataRead.pyx":446 - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): - * cdef np.ndarray[np.uint64_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset, unsigned long n_bytes, unsigned char swap): + * cdef np.ndarray[np.uint64_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array # <<<<<<<<<<<<<< * cdef unsigned long long i - * cdef unsigned long long mask = ((1 << bitCount) - 1) + * cdef unsigned long long mask = ((1 << bit_count) - 1) */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 446, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 446, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_numberOfRecords); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 446, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_number_of_records); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 446, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 446, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); @@ -7249,7 +7264,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 446, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 446, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_record_format) < 0) __PYX_ERR(0, 446, __pyx_L1_error) __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 446, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; @@ -7270,17 +7285,17 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_t_4 = 0; /* "dataRead.pyx":448 - * cdef np.ndarray[np.uint64_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array + * cdef np.ndarray[np.uint64_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array * cdef unsigned long long i - * cdef unsigned long long mask = ((1 << bitCount) - 1) # <<<<<<<<<<<<<< + * cdef unsigned long long mask = ((1 << bit_count) - 1) # <<<<<<<<<<<<<< * cdef unsigned long long temp8byte = 0 * cdef char temp8[8] */ - __pyx_v_mask = ((1 << __pyx_v_bitCount) - 1); + __pyx_v_mask = ((1 << __pyx_v_bit_count) - 1); /* "dataRead.pyx":449 * cdef unsigned long long i - * cdef unsigned long long mask = ((1 << bitCount) - 1) + * cdef unsigned long long mask = ((1 << bit_count) - 1) * cdef unsigned long long temp8byte = 0 # <<<<<<<<<<<<<< * cdef char temp8[8] * cdef char temp7[7] @@ -7290,37 +7305,37 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ /* "dataRead.pyx":454 * cdef char temp6[6] * cdef char temp5[5] - * if bitCount == 64: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * if bit_count == 64: # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ - __pyx_t_6 = ((__pyx_v_bitCount == 64) != 0); + __pyx_t_6 = ((__pyx_v_bit_count == 64) != 0); if (__pyx_t_6) { /* "dataRead.pyx":455 * cdef char temp5[5] - * if bitCount == 64: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * if bit_count == 64: + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * buf[i] = temp8byte */ - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":456 - * if bitCount == 64: - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * if bit_count == 64: + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * buf[i] = temp8byte * if swap == 0: */ - (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":457 - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * buf[i] = temp8byte # <<<<<<<<<<<<<< * if swap == 0: * return buf @@ -7336,7 +7351,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ } /* "dataRead.pyx":458 - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * buf[i] = temp8byte * if swap == 0: # <<<<<<<<<<<<<< * return buf @@ -7358,7 +7373,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ goto __pyx_L0; /* "dataRead.pyx":458 - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * buf[i] = temp8byte * if swap == 0: # <<<<<<<<<<<<<< * return buf @@ -7370,7 +7385,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ * return buf * else: * return buf.byteswap() # <<<<<<<<<<<<<< - * elif nBytes == 8: + * elif n_bytes == 8: * if swap == 0: */ /*else*/ { @@ -7403,94 +7418,94 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ /* "dataRead.pyx":454 * cdef char temp6[6] * cdef char temp5[5] - * if bitCount == 64: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * if bit_count == 64: # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ } /* "dataRead.pyx":462 * else: * return buf.byteswap() - * elif nBytes == 8: # <<<<<<<<<<<<<< + * elif n_bytes == 8: # <<<<<<<<<<<<<< * if swap == 0: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ - __pyx_t_6 = ((__pyx_v_nBytes == 8) != 0); + __pyx_t_6 = ((__pyx_v_n_bytes == 8) != 0); if (__pyx_t_6) { /* "dataRead.pyx":463 * return buf.byteswap() - * elif nBytes == 8: + * elif n_bytes == 8: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":464 - * elif nBytes == 8: + * elif n_bytes == 8: * if swap == 0: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift */ - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":465 * if swap == 0: - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ - (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":467 - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":468 * # right shift - * if bitOffset > 0: - * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp8byte = temp8byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 64: + * if bit_count < 64: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); + __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bit_offset); /* "dataRead.pyx":467 - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":470 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 64: # <<<<<<<<<<<<<< + * if bit_count < 64: # <<<<<<<<<<<<<< * temp8byte &= mask * buf[i] = temp8byte */ - __pyx_t_6 = ((__pyx_v_bitCount < 64) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 64) != 0); if (__pyx_t_6) { /* "dataRead.pyx":471 * # mask left part - * if bitCount < 64: + * if bit_count < 64: * temp8byte &= mask # <<<<<<<<<<<<<< * buf[i] = temp8byte * else: @@ -7498,20 +7513,20 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); /* "dataRead.pyx":470 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 64: # <<<<<<<<<<<<<< + * if bit_count < 64: # <<<<<<<<<<<<<< * temp8byte &= mask * buf[i] = temp8byte */ } /* "dataRead.pyx":472 - * if bitCount < 64: + * if bit_count < 64: * temp8byte &= mask * buf[i] = temp8byte # <<<<<<<<<<<<<< * else: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ __pyx_t_12 = __pyx_v_i; __pyx_t_11 = -1; @@ -7525,10 +7540,10 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ /* "dataRead.pyx":463 * return buf.byteswap() - * elif nBytes == 8: + * elif n_bytes == 8: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ goto __pyx_L7; } @@ -7536,95 +7551,95 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ /* "dataRead.pyx":474 * buf[i] = temp8byte * else: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp8, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp8, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp8byte = temp8[0]<<56 | temp8[1]<<48 | temp8[2]<<40 | temp8[3]<<32 | \ */ /*else*/ { - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":475 * else: - * for i in range(numberOfRecords): - * memcpy(&temp8, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp8, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * temp8byte = temp8[0]<<56 | temp8[1]<<48 | temp8[2]<<40 | temp8[3]<<32 | \ * temp8[4]<<24 | temp8[5]<<16 | temp8[6]<<8 | temp8[7] # swap bytes */ - (void)(memcpy((&__pyx_v_temp8), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp8), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":477 - * memcpy(&temp8, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp8, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp8byte = temp8[0]<<56 | temp8[1]<<48 | temp8[2]<<40 | temp8[3]<<32 | \ * temp8[4]<<24 | temp8[5]<<16 | temp8[6]<<8 | temp8[7] # swap bytes # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ __pyx_v_temp8byte = (((((((((__pyx_v_temp8[0]) << 56) | ((__pyx_v_temp8[1]) << 48)) | ((__pyx_v_temp8[2]) << 40)) | ((__pyx_v_temp8[3]) << 32)) | ((__pyx_v_temp8[4]) << 24)) | ((__pyx_v_temp8[5]) << 16)) | ((__pyx_v_temp8[6]) << 8)) | (__pyx_v_temp8[7])); /* "dataRead.pyx":479 * temp8[4]<<24 | temp8[5]<<16 | temp8[6]<<8 | temp8[7] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":480 * # right shift - * if bitOffset > 0: - * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp8byte = temp8byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 64: + * if bit_count < 64: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); + __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bit_offset); /* "dataRead.pyx":479 * temp8[4]<<24 | temp8[5]<<16 | temp8[6]<<8 | temp8[7] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":482 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 64: # <<<<<<<<<<<<<< + * if bit_count < 64: # <<<<<<<<<<<<<< * temp8byte &= mask * buf[i] = temp8byte */ - __pyx_t_6 = ((__pyx_v_bitCount < 64) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 64) != 0); if (__pyx_t_6) { /* "dataRead.pyx":483 * # mask left part - * if bitCount < 64: + * if bit_count < 64: * temp8byte &= mask # <<<<<<<<<<<<<< * buf[i] = temp8byte - * elif nBytes == 7: + * elif n_bytes == 7: */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); /* "dataRead.pyx":482 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 64: # <<<<<<<<<<<<<< + * if bit_count < 64: # <<<<<<<<<<<<<< * temp8byte &= mask * buf[i] = temp8byte */ } /* "dataRead.pyx":484 - * if bitCount < 64: + * if bit_count < 64: * temp8byte &= mask * buf[i] = temp8byte # <<<<<<<<<<<<<< - * elif nBytes == 7: + * elif n_bytes == 7: * if swap == 0: */ __pyx_t_13 = __pyx_v_i; @@ -7642,9 +7657,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ /* "dataRead.pyx":462 * else: * return buf.byteswap() - * elif nBytes == 8: # <<<<<<<<<<<<<< + * elif n_bytes == 8: # <<<<<<<<<<<<<< * if swap == 0: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ goto __pyx_L3; } @@ -7652,85 +7667,85 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ /* "dataRead.pyx":485 * temp8byte &= mask * buf[i] = temp8byte - * elif nBytes == 7: # <<<<<<<<<<<<<< + * elif n_bytes == 7: # <<<<<<<<<<<<<< * if swap == 0: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ - __pyx_t_6 = ((__pyx_v_nBytes == 7) != 0); + __pyx_t_6 = ((__pyx_v_n_bytes == 7) != 0); if (__pyx_t_6) { /* "dataRead.pyx":486 * buf[i] = temp8byte - * elif nBytes == 7: + * elif n_bytes == 7: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":487 - * elif nBytes == 7: + * elif n_bytes == 7: * if swap == 0: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift */ - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":488 * if swap == 0: - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ - (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":490 - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":491 * # right shift - * if bitOffset > 0: - * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp8byte = temp8byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 56: + * if bit_count < 56: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); + __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bit_offset); /* "dataRead.pyx":490 - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":493 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 56: # <<<<<<<<<<<<<< + * if bit_count < 56: # <<<<<<<<<<<<<< * temp8byte &= mask * buf[i] = temp8byte */ - __pyx_t_6 = ((__pyx_v_bitCount < 56) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 56) != 0); if (__pyx_t_6) { /* "dataRead.pyx":494 * # mask left part - * if bitCount < 56: + * if bit_count < 56: * temp8byte &= mask # <<<<<<<<<<<<<< * buf[i] = temp8byte * else: @@ -7738,20 +7753,20 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); /* "dataRead.pyx":493 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 56: # <<<<<<<<<<<<<< + * if bit_count < 56: # <<<<<<<<<<<<<< * temp8byte &= mask * buf[i] = temp8byte */ } /* "dataRead.pyx":495 - * if bitCount < 56: + * if bit_count < 56: * temp8byte &= mask * buf[i] = temp8byte # <<<<<<<<<<<<<< * else: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ __pyx_t_14 = __pyx_v_i; __pyx_t_11 = -1; @@ -7765,10 +7780,10 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ /* "dataRead.pyx":486 * buf[i] = temp8byte - * elif nBytes == 7: + * elif n_bytes == 7: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ goto __pyx_L16; } @@ -7776,95 +7791,95 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ /* "dataRead.pyx":497 * buf[i] = temp8byte * else: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp7, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp7, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp8byte = temp7[0]<<48 | temp7[1]<<40 | temp7[2]<<32 | \ */ /*else*/ { - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":498 * else: - * for i in range(numberOfRecords): - * memcpy(&temp7, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp7, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * temp8byte = temp7[0]<<48 | temp7[1]<<40 | temp7[2]<<32 | \ * temp7[3]<<24 | temp7[4]<<16 | temp7[5]<<8 | temp7[6] # swap bytes */ - (void)(memcpy((&__pyx_v_temp7), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp7), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":500 - * memcpy(&temp7, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp7, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp8byte = temp7[0]<<48 | temp7[1]<<40 | temp7[2]<<32 | \ * temp7[3]<<24 | temp7[4]<<16 | temp7[5]<<8 | temp7[6] # swap bytes # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ __pyx_v_temp8byte = ((((((((__pyx_v_temp7[0]) << 48) | ((__pyx_v_temp7[1]) << 40)) | ((__pyx_v_temp7[2]) << 32)) | ((__pyx_v_temp7[3]) << 24)) | ((__pyx_v_temp7[4]) << 16)) | ((__pyx_v_temp7[5]) << 8)) | (__pyx_v_temp7[6])); /* "dataRead.pyx":502 * temp7[3]<<24 | temp7[4]<<16 | temp7[5]<<8 | temp7[6] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":503 * # right shift - * if bitOffset > 0: - * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp8byte = temp8byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 56: + * if bit_count < 56: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); + __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bit_offset); /* "dataRead.pyx":502 * temp7[3]<<24 | temp7[4]<<16 | temp7[5]<<8 | temp7[6] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":505 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 56: # <<<<<<<<<<<<<< + * if bit_count < 56: # <<<<<<<<<<<<<< * temp8byte &= mask * buf[i] = temp8byte */ - __pyx_t_6 = ((__pyx_v_bitCount < 56) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 56) != 0); if (__pyx_t_6) { /* "dataRead.pyx":506 * # mask left part - * if bitCount < 56: + * if bit_count < 56: * temp8byte &= mask # <<<<<<<<<<<<<< * buf[i] = temp8byte - * elif nBytes == 6: + * elif n_bytes == 6: */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); /* "dataRead.pyx":505 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 56: # <<<<<<<<<<<<<< + * if bit_count < 56: # <<<<<<<<<<<<<< * temp8byte &= mask * buf[i] = temp8byte */ } /* "dataRead.pyx":507 - * if bitCount < 56: + * if bit_count < 56: * temp8byte &= mask * buf[i] = temp8byte # <<<<<<<<<<<<<< - * elif nBytes == 6: + * elif n_bytes == 6: * if swap == 0: */ __pyx_t_15 = __pyx_v_i; @@ -7882,9 +7897,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ /* "dataRead.pyx":485 * temp8byte &= mask * buf[i] = temp8byte - * elif nBytes == 7: # <<<<<<<<<<<<<< + * elif n_bytes == 7: # <<<<<<<<<<<<<< * if swap == 0: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ goto __pyx_L3; } @@ -7892,85 +7907,85 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ /* "dataRead.pyx":508 * temp8byte &= mask * buf[i] = temp8byte - * elif nBytes == 6: # <<<<<<<<<<<<<< + * elif n_bytes == 6: # <<<<<<<<<<<<<< * if swap == 0: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ - __pyx_t_6 = ((__pyx_v_nBytes == 6) != 0); + __pyx_t_6 = ((__pyx_v_n_bytes == 6) != 0); if (__pyx_t_6) { /* "dataRead.pyx":509 * buf[i] = temp8byte - * elif nBytes == 6: + * elif n_bytes == 6: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":510 - * elif nBytes == 6: + * elif n_bytes == 6: * if swap == 0: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift */ - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":511 * if swap == 0: - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ - (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":513 - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":514 * # right shift - * if bitOffset > 0: - * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp8byte = temp8byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 48: + * if bit_count < 48: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); + __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bit_offset); /* "dataRead.pyx":513 - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":516 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 48: # <<<<<<<<<<<<<< + * if bit_count < 48: # <<<<<<<<<<<<<< * temp8byte &= mask * buf[i] = temp8byte */ - __pyx_t_6 = ((__pyx_v_bitCount < 48) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 48) != 0); if (__pyx_t_6) { /* "dataRead.pyx":517 * # mask left part - * if bitCount < 48: + * if bit_count < 48: * temp8byte &= mask # <<<<<<<<<<<<<< * buf[i] = temp8byte * else: @@ -7978,20 +7993,20 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); /* "dataRead.pyx":516 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 48: # <<<<<<<<<<<<<< + * if bit_count < 48: # <<<<<<<<<<<<<< * temp8byte &= mask * buf[i] = temp8byte */ } /* "dataRead.pyx":518 - * if bitCount < 48: + * if bit_count < 48: * temp8byte &= mask * buf[i] = temp8byte # <<<<<<<<<<<<<< * else: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ __pyx_t_16 = __pyx_v_i; __pyx_t_11 = -1; @@ -8005,10 +8020,10 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ /* "dataRead.pyx":509 * buf[i] = temp8byte - * elif nBytes == 6: + * elif n_bytes == 6: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ goto __pyx_L25; } @@ -8016,95 +8031,95 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ /* "dataRead.pyx":520 * buf[i] = temp8byte * else: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp6, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp6, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp8byte = temp6[0]<<40 | temp6[1]<<32 | temp6[2]<<24 | \ */ /*else*/ { - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":521 * else: - * for i in range(numberOfRecords): - * memcpy(&temp6, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp6, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * temp8byte = temp6[0]<<40 | temp6[1]<<32 | temp6[2]<<24 | \ * temp6[3]<<16 | temp6[4]<<8 | temp6[5] # swap bytes */ - (void)(memcpy((&__pyx_v_temp6), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp6), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":523 - * memcpy(&temp6, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp6, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp8byte = temp6[0]<<40 | temp6[1]<<32 | temp6[2]<<24 | \ * temp6[3]<<16 | temp6[4]<<8 | temp6[5] # swap bytes # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ __pyx_v_temp8byte = (((((((__pyx_v_temp6[0]) << 40) | ((__pyx_v_temp6[1]) << 32)) | ((__pyx_v_temp6[2]) << 24)) | ((__pyx_v_temp6[3]) << 16)) | ((__pyx_v_temp6[4]) << 8)) | (__pyx_v_temp6[5])); /* "dataRead.pyx":525 * temp6[3]<<16 | temp6[4]<<8 | temp6[5] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":526 * # right shift - * if bitOffset > 0: - * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp8byte = temp8byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 48: + * if bit_count < 48: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); + __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bit_offset); /* "dataRead.pyx":525 * temp6[3]<<16 | temp6[4]<<8 | temp6[5] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":528 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 48: # <<<<<<<<<<<<<< + * if bit_count < 48: # <<<<<<<<<<<<<< * temp8byte &= mask * buf[i] = temp8byte */ - __pyx_t_6 = ((__pyx_v_bitCount < 48) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 48) != 0); if (__pyx_t_6) { /* "dataRead.pyx":529 * # mask left part - * if bitCount < 48: + * if bit_count < 48: * temp8byte &= mask # <<<<<<<<<<<<<< * buf[i] = temp8byte - * elif nBytes == 5: + * elif n_bytes == 5: */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); /* "dataRead.pyx":528 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 48: # <<<<<<<<<<<<<< + * if bit_count < 48: # <<<<<<<<<<<<<< * temp8byte &= mask * buf[i] = temp8byte */ } /* "dataRead.pyx":530 - * if bitCount < 48: + * if bit_count < 48: * temp8byte &= mask * buf[i] = temp8byte # <<<<<<<<<<<<<< - * elif nBytes == 5: + * elif n_bytes == 5: * if swap == 0: */ __pyx_t_17 = __pyx_v_i; @@ -8122,9 +8137,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ /* "dataRead.pyx":508 * temp8byte &= mask * buf[i] = temp8byte - * elif nBytes == 6: # <<<<<<<<<<<<<< + * elif n_bytes == 6: # <<<<<<<<<<<<<< * if swap == 0: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ goto __pyx_L3; } @@ -8132,85 +8147,85 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ /* "dataRead.pyx":531 * temp8byte &= mask * buf[i] = temp8byte - * elif nBytes == 5: # <<<<<<<<<<<<<< + * elif n_bytes == 5: # <<<<<<<<<<<<<< * if swap == 0: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ - __pyx_t_6 = ((__pyx_v_nBytes == 5) != 0); + __pyx_t_6 = ((__pyx_v_n_bytes == 5) != 0); if (__pyx_t_6) { /* "dataRead.pyx":532 * buf[i] = temp8byte - * elif nBytes == 5: + * elif n_bytes == 5: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":533 - * elif nBytes == 5: + * elif n_bytes == 5: * if swap == 0: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift */ - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":534 * if swap == 0: - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ - (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":536 - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":537 * # right shift - * if bitOffset > 0: - * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp8byte = temp8byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 32: + * if bit_count < 32: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); + __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bit_offset); /* "dataRead.pyx":536 - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":539 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 32: # <<<<<<<<<<<<<< + * if bit_count < 32: # <<<<<<<<<<<<<< * temp8byte &= mask * buf[i] = temp8byte */ - __pyx_t_6 = ((__pyx_v_bitCount < 32) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 32) != 0); if (__pyx_t_6) { /* "dataRead.pyx":540 * # mask left part - * if bitCount < 32: + * if bit_count < 32: * temp8byte &= mask # <<<<<<<<<<<<<< * buf[i] = temp8byte * else: @@ -8218,20 +8233,20 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); /* "dataRead.pyx":539 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 32: # <<<<<<<<<<<<<< + * if bit_count < 32: # <<<<<<<<<<<<<< * temp8byte &= mask * buf[i] = temp8byte */ } /* "dataRead.pyx":541 - * if bitCount < 32: + * if bit_count < 32: * temp8byte &= mask * buf[i] = temp8byte # <<<<<<<<<<<<<< * else: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ __pyx_t_18 = __pyx_v_i; __pyx_t_11 = -1; @@ -8245,10 +8260,10 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ /* "dataRead.pyx":532 * buf[i] = temp8byte - * elif nBytes == 5: + * elif n_bytes == 5: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ goto __pyx_L34; } @@ -8256,75 +8271,75 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ /* "dataRead.pyx":543 * buf[i] = temp8byte * else: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp5, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp5, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp8byte = temp5[0]<<32 | temp5[1]<<24 | \ */ /*else*/ { - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":544 * else: - * for i in range(numberOfRecords): - * memcpy(&temp5, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp5, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * temp8byte = temp5[0]<<32 | temp5[1]<<24 | \ * temp5[2]<<16 | temp5[3]<<8 | temp5[4] # swap bytes */ - (void)(memcpy((&__pyx_v_temp5), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp5), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":546 - * memcpy(&temp5, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp5, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp8byte = temp5[0]<<32 | temp5[1]<<24 | \ * temp5[2]<<16 | temp5[3]<<8 | temp5[4] # swap bytes # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ __pyx_v_temp8byte = ((((((__pyx_v_temp5[0]) << 32) | ((__pyx_v_temp5[1]) << 24)) | ((__pyx_v_temp5[2]) << 16)) | ((__pyx_v_temp5[3]) << 8)) | (__pyx_v_temp5[4])); /* "dataRead.pyx":548 * temp5[2]<<16 | temp5[3]<<8 | temp5[4] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":549 * # right shift - * if bitOffset > 0: - * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp8byte = temp8byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 32: + * if bit_count < 32: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); + __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bit_offset); /* "dataRead.pyx":548 * temp5[2]<<16 | temp5[3]<<8 | temp5[4] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":551 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 32: # <<<<<<<<<<<<<< + * if bit_count < 32: # <<<<<<<<<<<<<< * temp8byte &= mask * buf[i] = temp8byte */ - __pyx_t_6 = ((__pyx_v_bitCount < 32) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 32) != 0); if (__pyx_t_6) { /* "dataRead.pyx":552 * # mask left part - * if bitCount < 32: + * if bit_count < 32: * temp8byte &= mask # <<<<<<<<<<<<<< * buf[i] = temp8byte * return buf @@ -8332,16 +8347,16 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); /* "dataRead.pyx":551 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 32: # <<<<<<<<<<<<<< + * if bit_count < 32: # <<<<<<<<<<<<<< * temp8byte &= mask * buf[i] = temp8byte */ } /* "dataRead.pyx":553 - * if bitCount < 32: + * if bit_count < 32: * temp8byte &= mask * buf[i] = temp8byte # <<<<<<<<<<<<<< * return buf @@ -8362,9 +8377,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ /* "dataRead.pyx":531 * temp8byte &= mask * buf[i] = temp8byte - * elif nBytes == 5: # <<<<<<<<<<<<<< + * elif n_bytes == 5: # <<<<<<<<<<<<<< * if swap == 0: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ } __pyx_L3:; @@ -8374,7 +8389,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ * buf[i] = temp8byte * return buf # <<<<<<<<<<<<<< * - * cdef inline dataReadLongLong(const char* bita, str RecordFormat, unsigned long long numberOfRecords, + * cdef inline read_signed_longlong(const char* bit_stream, str record_format, unsigned long long number_of_records, */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject *)__pyx_v_buf)); @@ -8384,9 +8399,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ /* "dataRead.pyx":443 * return buf * - * cdef inline dataReadULongLong(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): + * cdef inline read_unsigned_longlong(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset, unsigned long n_bytes, unsigned char swap): */ /* function exit code */ @@ -8401,7 +8416,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_buf.rcbuffer->pybuffer); __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} - __Pyx_AddTraceback("dataRead.dataReadULongLong", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("dataRead.read_unsigned_longlong", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; goto __pyx_L2; __pyx_L0:; @@ -8416,19 +8431,19 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadULongLong(char const *_ /* "dataRead.pyx":556 * return buf * - * cdef inline dataReadLongLong(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): + * cdef inline read_signed_longlong(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset, unsigned long n_bytes, unsigned char swap): */ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_bitCount, unsigned char __pyx_v_bitOffset, unsigned long __pyx_v_nBytes, unsigned char __pyx_v_swap) { +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_signed_longlong(char const *__pyx_v_bit_stream, PyObject *__pyx_v_record_format, unsigned PY_LONG_LONG __pyx_v_number_of_records, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_pos_byte_beg, unsigned long __pyx_v_bit_count, unsigned char __pyx_v_bit_offset, unsigned long __pyx_v_n_bytes, unsigned char __pyx_v_swap) { PyArrayObject *__pyx_v_buf = 0; unsigned PY_LONG_LONG __pyx_v_i; PY_LONG_LONG __pyx_v_mask; PY_LONG_LONG __pyx_v_temp8byte; - long __pyx_v_signBit; - PY_LONG_LONG __pyx_v_signBitMask; - PY_LONG_LONG __pyx_v_signExtend; + long __pyx_v_sign_bit; + PY_LONG_LONG __pyx_v_sign_bit_mask; + PY_LONG_LONG __pyx_v_sign_extend; char __pyx_v_temp8[8]; char __pyx_v_temp7[7]; char __pyx_v_temp6[6]; @@ -8456,25 +8471,25 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ unsigned PY_LONG_LONG __pyx_t_17; unsigned PY_LONG_LONG __pyx_t_18; unsigned PY_LONG_LONG __pyx_t_19; - __Pyx_RefNannySetupContext("dataReadLongLong", 0); + __Pyx_RefNannySetupContext("read_signed_longlong", 0); __pyx_pybuffer_buf.pybuffer.buf = NULL; __pyx_pybuffer_buf.refcount = 0; __pyx_pybuffernd_buf.data = NULL; __pyx_pybuffernd_buf.rcbuffer = &__pyx_pybuffer_buf; /* "dataRead.pyx":559 - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): - * cdef np.ndarray[np.int64_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset, unsigned long n_bytes, unsigned char swap): + * cdef np.ndarray[np.int64_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array # <<<<<<<<<<<<<< * cdef unsigned long long i - * cdef long long mask = ((1 << bitCount) - 1) + * cdef long long mask = ((1 << bit_count) - 1) */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 559, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 559, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_numberOfRecords); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 559, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_number_of_records); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 559, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 559, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); @@ -8483,7 +8498,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 559, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 559, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_record_format) < 0) __PYX_ERR(0, 559, __pyx_L1_error) __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 559, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; @@ -8504,84 +8519,84 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_t_4 = 0; /* "dataRead.pyx":561 - * cdef np.ndarray[np.int64_t] buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array + * cdef np.ndarray[np.int64_t] buf = np.empty(number_of_records, dtype=record_format) # return numpy array * cdef unsigned long long i - * cdef long long mask = ((1 << bitCount) - 1) # <<<<<<<<<<<<<< + * cdef long long mask = ((1 << bit_count) - 1) # <<<<<<<<<<<<<< * cdef long long temp8byte = 0 - * cdef long signBit = 0 + * cdef long sign_bit = 0 */ - __pyx_v_mask = ((1 << __pyx_v_bitCount) - 1); + __pyx_v_mask = ((1 << __pyx_v_bit_count) - 1); /* "dataRead.pyx":562 * cdef unsigned long long i - * cdef long long mask = ((1 << bitCount) - 1) + * cdef long long mask = ((1 << bit_count) - 1) * cdef long long temp8byte = 0 # <<<<<<<<<<<<<< - * cdef long signBit = 0 - * cdef long long signBitMask = (1 << (bitCount-1)) + * cdef long sign_bit = 0 + * cdef long long sign_bit_mask = (1 << (bit_count-1)) */ __pyx_v_temp8byte = 0; /* "dataRead.pyx":563 - * cdef long long mask = ((1 << bitCount) - 1) + * cdef long long mask = ((1 << bit_count) - 1) * cdef long long temp8byte = 0 - * cdef long signBit = 0 # <<<<<<<<<<<<<< - * cdef long long signBitMask = (1 << (bitCount-1)) - * cdef long long signExtend = ((1 << (64 - bitCount)) - 1) << bitCount + * cdef long sign_bit = 0 # <<<<<<<<<<<<<< + * cdef long long sign_bit_mask = (1 << (bit_count-1)) + * cdef long long sign_extend = ((1 << (64 - bit_count)) - 1) << bit_count */ - __pyx_v_signBit = 0; + __pyx_v_sign_bit = 0; /* "dataRead.pyx":564 * cdef long long temp8byte = 0 - * cdef long signBit = 0 - * cdef long long signBitMask = (1 << (bitCount-1)) # <<<<<<<<<<<<<< - * cdef long long signExtend = ((1 << (64 - bitCount)) - 1) << bitCount + * cdef long sign_bit = 0 + * cdef long long sign_bit_mask = (1 << (bit_count-1)) # <<<<<<<<<<<<<< + * cdef long long sign_extend = ((1 << (64 - bit_count)) - 1) << bit_count * cdef char temp8[8] */ - __pyx_v_signBitMask = (1 << (__pyx_v_bitCount - 1)); + __pyx_v_sign_bit_mask = (1 << (__pyx_v_bit_count - 1)); /* "dataRead.pyx":565 - * cdef long signBit = 0 - * cdef long long signBitMask = (1 << (bitCount-1)) - * cdef long long signExtend = ((1 << (64 - bitCount)) - 1) << bitCount # <<<<<<<<<<<<<< + * cdef long sign_bit = 0 + * cdef long long sign_bit_mask = (1 << (bit_count-1)) + * cdef long long sign_extend = ((1 << (64 - bit_count)) - 1) << bit_count # <<<<<<<<<<<<<< * cdef char temp8[8] * cdef char temp7[7] */ - __pyx_v_signExtend = (((1 << (64 - __pyx_v_bitCount)) - 1) << __pyx_v_bitCount); + __pyx_v_sign_extend = (((1 << (64 - __pyx_v_bit_count)) - 1) << __pyx_v_bit_count); /* "dataRead.pyx":570 * cdef char temp6[6] * cdef char temp5[5] - * if bitCount == 64: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * if bit_count == 64: # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ - __pyx_t_6 = ((__pyx_v_bitCount == 64) != 0); + __pyx_t_6 = ((__pyx_v_bit_count == 64) != 0); if (__pyx_t_6) { /* "dataRead.pyx":571 * cdef char temp5[5] - * if bitCount == 64: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * if bit_count == 64: + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * buf[i] = temp8byte */ - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":572 - * if bitCount == 64: - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * if bit_count == 64: + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * buf[i] = temp8byte * if swap == 0: */ - (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":573 - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * buf[i] = temp8byte # <<<<<<<<<<<<<< * if swap == 0: * return buf @@ -8597,7 +8612,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ } /* "dataRead.pyx":574 - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * buf[i] = temp8byte * if swap == 0: # <<<<<<<<<<<<<< * return buf @@ -8619,7 +8634,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ goto __pyx_L0; /* "dataRead.pyx":574 - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * buf[i] = temp8byte * if swap == 0: # <<<<<<<<<<<<<< * return buf @@ -8631,7 +8646,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ * return buf * else: * return buf.byteswap() # <<<<<<<<<<<<<< - * elif nBytes == 8: + * elif n_bytes == 8: * if swap == 0: */ /*else*/ { @@ -8664,152 +8679,152 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ /* "dataRead.pyx":570 * cdef char temp6[6] * cdef char temp5[5] - * if bitCount == 64: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * if bit_count == 64: # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ } /* "dataRead.pyx":578 * else: * return buf.byteswap() - * elif nBytes == 8: # <<<<<<<<<<<<<< + * elif n_bytes == 8: # <<<<<<<<<<<<<< * if swap == 0: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ - __pyx_t_6 = ((__pyx_v_nBytes == 8) != 0); + __pyx_t_6 = ((__pyx_v_n_bytes == 8) != 0); if (__pyx_t_6) { /* "dataRead.pyx":579 * return buf.byteswap() - * elif nBytes == 8: + * elif n_bytes == 8: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":580 - * elif nBytes == 8: + * elif n_bytes == 8: * if swap == 0: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift */ - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":581 * if swap == 0: - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ - (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":583 - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":584 * # right shift - * if bitOffset > 0: - * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp8byte = temp8byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 64: + * if bit_count < 64: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); + __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bit_offset); /* "dataRead.pyx":583 - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":586 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 64: # <<<<<<<<<<<<<< + * if bit_count < 64: # <<<<<<<<<<<<<< * temp8byte &= mask - * signBit = temp8byte & signBitMask + * sign_bit = temp8byte & sign_bit_mask */ - __pyx_t_6 = ((__pyx_v_bitCount < 64) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 64) != 0); if (__pyx_t_6) { /* "dataRead.pyx":587 * # mask left part - * if bitCount < 64: + * if bit_count < 64: * temp8byte &= mask # <<<<<<<<<<<<<< - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); /* "dataRead.pyx":586 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 64: # <<<<<<<<<<<<<< + * if bit_count < 64: # <<<<<<<<<<<<<< * temp8byte &= mask - * signBit = temp8byte & signBitMask + * sign_bit = temp8byte & sign_bit_mask */ } /* "dataRead.pyx":588 - * if bitCount < 64: + * if bit_count < 64: * temp8byte &= mask - * signBit = temp8byte & signBitMask # <<<<<<<<<<<<<< - * if signBit: # negative value, sign extend - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask # <<<<<<<<<<<<<< + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend */ - __pyx_v_signBit = (__pyx_v_temp8byte & __pyx_v_signBitMask); + __pyx_v_sign_bit = (__pyx_v_temp8byte & __pyx_v_sign_bit_mask); /* "dataRead.pyx":589 * temp8byte &= mask - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp8byte |= sign_extend * buf[i] = temp8byte */ - __pyx_t_6 = (__pyx_v_signBit != 0); + __pyx_t_6 = (__pyx_v_sign_bit != 0); if (__pyx_t_6) { /* "dataRead.pyx":590 - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend - * temp8byte |= signExtend # <<<<<<<<<<<<<< + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend # <<<<<<<<<<<<<< * buf[i] = temp8byte * else: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_signExtend); + __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_sign_extend); /* "dataRead.pyx":589 * temp8byte &= mask - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp8byte |= sign_extend * buf[i] = temp8byte */ } /* "dataRead.pyx":591 - * if signBit: # negative value, sign extend - * temp8byte |= signExtend + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend * buf[i] = temp8byte # <<<<<<<<<<<<<< * else: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ __pyx_t_12 = __pyx_v_i; __pyx_t_11 = -1; @@ -8823,10 +8838,10 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ /* "dataRead.pyx":579 * return buf.byteswap() - * elif nBytes == 8: + * elif n_bytes == 8: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ goto __pyx_L7; } @@ -8834,132 +8849,132 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ /* "dataRead.pyx":593 * buf[i] = temp8byte * else: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp8, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp8, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp8byte = temp8[0]<<56 | temp8[1]<<48 | temp8[2]<<40 | temp8[3]<<32 | \ */ /*else*/ { - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":594 * else: - * for i in range(numberOfRecords): - * memcpy(&temp8, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp8, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * temp8byte = temp8[0]<<56 | temp8[1]<<48 | temp8[2]<<40 | temp8[3]<<32 | \ * temp8[4]<<24 | temp8[5]<<16 | temp8[6]<<8 | temp8[7] # swap bytes */ - (void)(memcpy((&__pyx_v_temp8), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp8), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":596 - * memcpy(&temp8, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp8, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp8byte = temp8[0]<<56 | temp8[1]<<48 | temp8[2]<<40 | temp8[3]<<32 | \ * temp8[4]<<24 | temp8[5]<<16 | temp8[6]<<8 | temp8[7] # swap bytes # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ __pyx_v_temp8byte = (((((((((__pyx_v_temp8[0]) << 56) | ((__pyx_v_temp8[1]) << 48)) | ((__pyx_v_temp8[2]) << 40)) | ((__pyx_v_temp8[3]) << 32)) | ((__pyx_v_temp8[4]) << 24)) | ((__pyx_v_temp8[5]) << 16)) | ((__pyx_v_temp8[6]) << 8)) | (__pyx_v_temp8[7])); /* "dataRead.pyx":598 * temp8[4]<<24 | temp8[5]<<16 | temp8[6]<<8 | temp8[7] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":599 * # right shift - * if bitOffset > 0: - * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp8byte = temp8byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 64: + * if bit_count < 64: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); + __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bit_offset); /* "dataRead.pyx":598 * temp8[4]<<24 | temp8[5]<<16 | temp8[6]<<8 | temp8[7] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":601 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 64: # <<<<<<<<<<<<<< + * if bit_count < 64: # <<<<<<<<<<<<<< * temp8byte &= mask - * signBit = temp8byte & signBitMask + * sign_bit = temp8byte & sign_bit_mask */ - __pyx_t_6 = ((__pyx_v_bitCount < 64) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 64) != 0); if (__pyx_t_6) { /* "dataRead.pyx":602 * # mask left part - * if bitCount < 64: + * if bit_count < 64: * temp8byte &= mask # <<<<<<<<<<<<<< - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); /* "dataRead.pyx":601 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 64: # <<<<<<<<<<<<<< + * if bit_count < 64: # <<<<<<<<<<<<<< * temp8byte &= mask - * signBit = temp8byte & signBitMask + * sign_bit = temp8byte & sign_bit_mask */ } /* "dataRead.pyx":603 - * if bitCount < 64: + * if bit_count < 64: * temp8byte &= mask - * signBit = temp8byte & signBitMask # <<<<<<<<<<<<<< - * if signBit: # negative value, sign extend - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask # <<<<<<<<<<<<<< + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend */ - __pyx_v_signBit = (__pyx_v_temp8byte & __pyx_v_signBitMask); + __pyx_v_sign_bit = (__pyx_v_temp8byte & __pyx_v_sign_bit_mask); /* "dataRead.pyx":604 * temp8byte &= mask - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp8byte |= sign_extend * buf[i] = temp8byte */ - __pyx_t_6 = (__pyx_v_signBit != 0); + __pyx_t_6 = (__pyx_v_sign_bit != 0); if (__pyx_t_6) { /* "dataRead.pyx":605 - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend - * temp8byte |= signExtend # <<<<<<<<<<<<<< + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend # <<<<<<<<<<<<<< * buf[i] = temp8byte - * elif nBytes == 7: + * elif n_bytes == 7: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_signExtend); + __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_sign_extend); /* "dataRead.pyx":604 * temp8byte &= mask - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp8byte |= sign_extend * buf[i] = temp8byte */ } /* "dataRead.pyx":606 - * if signBit: # negative value, sign extend - * temp8byte |= signExtend + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend * buf[i] = temp8byte # <<<<<<<<<<<<<< - * elif nBytes == 7: + * elif n_bytes == 7: * if swap == 0: */ __pyx_t_13 = __pyx_v_i; @@ -8977,153 +8992,153 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ /* "dataRead.pyx":578 * else: * return buf.byteswap() - * elif nBytes == 8: # <<<<<<<<<<<<<< + * elif n_bytes == 8: # <<<<<<<<<<<<<< * if swap == 0: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ goto __pyx_L3; } /* "dataRead.pyx":607 - * temp8byte |= signExtend + * temp8byte |= sign_extend * buf[i] = temp8byte - * elif nBytes == 7: # <<<<<<<<<<<<<< + * elif n_bytes == 7: # <<<<<<<<<<<<<< * if swap == 0: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ - __pyx_t_6 = ((__pyx_v_nBytes == 7) != 0); + __pyx_t_6 = ((__pyx_v_n_bytes == 7) != 0); if (__pyx_t_6) { /* "dataRead.pyx":608 * buf[i] = temp8byte - * elif nBytes == 7: + * elif n_bytes == 7: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":609 - * elif nBytes == 7: + * elif n_bytes == 7: * if swap == 0: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift */ - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":610 * if swap == 0: - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ - (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":612 - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":613 * # right shift - * if bitOffset > 0: - * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp8byte = temp8byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 56: + * if bit_count < 56: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); + __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bit_offset); /* "dataRead.pyx":612 - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":615 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 56: # <<<<<<<<<<<<<< + * if bit_count < 56: # <<<<<<<<<<<<<< * temp8byte &= mask - * signBit = temp8byte & signBitMask + * sign_bit = temp8byte & sign_bit_mask */ - __pyx_t_6 = ((__pyx_v_bitCount < 56) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 56) != 0); if (__pyx_t_6) { /* "dataRead.pyx":616 * # mask left part - * if bitCount < 56: + * if bit_count < 56: * temp8byte &= mask # <<<<<<<<<<<<<< - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); /* "dataRead.pyx":615 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 56: # <<<<<<<<<<<<<< + * if bit_count < 56: # <<<<<<<<<<<<<< * temp8byte &= mask - * signBit = temp8byte & signBitMask + * sign_bit = temp8byte & sign_bit_mask */ } /* "dataRead.pyx":617 - * if bitCount < 56: + * if bit_count < 56: * temp8byte &= mask - * signBit = temp8byte & signBitMask # <<<<<<<<<<<<<< - * if signBit: # negative value, sign extend - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask # <<<<<<<<<<<<<< + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend */ - __pyx_v_signBit = (__pyx_v_temp8byte & __pyx_v_signBitMask); + __pyx_v_sign_bit = (__pyx_v_temp8byte & __pyx_v_sign_bit_mask); /* "dataRead.pyx":618 * temp8byte &= mask - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp8byte |= sign_extend * buf[i] = temp8byte */ - __pyx_t_6 = (__pyx_v_signBit != 0); + __pyx_t_6 = (__pyx_v_sign_bit != 0); if (__pyx_t_6) { /* "dataRead.pyx":619 - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend - * temp8byte |= signExtend # <<<<<<<<<<<<<< + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend # <<<<<<<<<<<<<< * buf[i] = temp8byte * else: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_signExtend); + __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_sign_extend); /* "dataRead.pyx":618 * temp8byte &= mask - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp8byte |= sign_extend * buf[i] = temp8byte */ } /* "dataRead.pyx":620 - * if signBit: # negative value, sign extend - * temp8byte |= signExtend + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend * buf[i] = temp8byte # <<<<<<<<<<<<<< * else: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ __pyx_t_14 = __pyx_v_i; __pyx_t_11 = -1; @@ -9137,10 +9152,10 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ /* "dataRead.pyx":608 * buf[i] = temp8byte - * elif nBytes == 7: + * elif n_bytes == 7: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ goto __pyx_L18; } @@ -9148,132 +9163,132 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ /* "dataRead.pyx":622 * buf[i] = temp8byte * else: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp7, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp7, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp8byte = temp7[0]<<48 | temp7[1]<<40 | temp7[2]<<32 | \ */ /*else*/ { - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":623 * else: - * for i in range(numberOfRecords): - * memcpy(&temp7, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp7, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * temp8byte = temp7[0]<<48 | temp7[1]<<40 | temp7[2]<<32 | \ * temp7[3]<<24 | temp7[4]<<16 | temp7[5]<<8 | temp7[6] # swap bytes */ - (void)(memcpy((&__pyx_v_temp7), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp7), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":625 - * memcpy(&temp7, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp7, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp8byte = temp7[0]<<48 | temp7[1]<<40 | temp7[2]<<32 | \ * temp7[3]<<24 | temp7[4]<<16 | temp7[5]<<8 | temp7[6] # swap bytes # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ __pyx_v_temp8byte = ((((((((__pyx_v_temp7[0]) << 48) | ((__pyx_v_temp7[1]) << 40)) | ((__pyx_v_temp7[2]) << 32)) | ((__pyx_v_temp7[3]) << 24)) | ((__pyx_v_temp7[4]) << 16)) | ((__pyx_v_temp7[5]) << 8)) | (__pyx_v_temp7[6])); /* "dataRead.pyx":627 * temp7[3]<<24 | temp7[4]<<16 | temp7[5]<<8 | temp7[6] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":628 * # right shift - * if bitOffset > 0: - * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp8byte = temp8byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 56: + * if bit_count < 56: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); + __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bit_offset); /* "dataRead.pyx":627 * temp7[3]<<24 | temp7[4]<<16 | temp7[5]<<8 | temp7[6] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":630 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 56: # <<<<<<<<<<<<<< + * if bit_count < 56: # <<<<<<<<<<<<<< * temp8byte &= mask - * signBit = temp8byte & signBitMask + * sign_bit = temp8byte & sign_bit_mask */ - __pyx_t_6 = ((__pyx_v_bitCount < 56) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 56) != 0); if (__pyx_t_6) { /* "dataRead.pyx":631 * # mask left part - * if bitCount < 56: + * if bit_count < 56: * temp8byte &= mask # <<<<<<<<<<<<<< - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); /* "dataRead.pyx":630 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 56: # <<<<<<<<<<<<<< + * if bit_count < 56: # <<<<<<<<<<<<<< * temp8byte &= mask - * signBit = temp8byte & signBitMask + * sign_bit = temp8byte & sign_bit_mask */ } /* "dataRead.pyx":632 - * if bitCount < 56: + * if bit_count < 56: * temp8byte &= mask - * signBit = temp8byte & signBitMask # <<<<<<<<<<<<<< - * if signBit: # negative value, sign extend - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask # <<<<<<<<<<<<<< + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend */ - __pyx_v_signBit = (__pyx_v_temp8byte & __pyx_v_signBitMask); + __pyx_v_sign_bit = (__pyx_v_temp8byte & __pyx_v_sign_bit_mask); /* "dataRead.pyx":633 * temp8byte &= mask - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp8byte |= sign_extend * buf[i] = temp8byte */ - __pyx_t_6 = (__pyx_v_signBit != 0); + __pyx_t_6 = (__pyx_v_sign_bit != 0); if (__pyx_t_6) { /* "dataRead.pyx":634 - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend - * temp8byte |= signExtend # <<<<<<<<<<<<<< + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend # <<<<<<<<<<<<<< * buf[i] = temp8byte - * elif nBytes == 6: + * elif n_bytes == 6: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_signExtend); + __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_sign_extend); /* "dataRead.pyx":633 * temp8byte &= mask - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp8byte |= sign_extend * buf[i] = temp8byte */ } /* "dataRead.pyx":635 - * if signBit: # negative value, sign extend - * temp8byte |= signExtend + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend * buf[i] = temp8byte # <<<<<<<<<<<<<< - * elif nBytes == 6: + * elif n_bytes == 6: * if swap == 0: */ __pyx_t_15 = __pyx_v_i; @@ -9289,155 +9304,155 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_L18:; /* "dataRead.pyx":607 - * temp8byte |= signExtend + * temp8byte |= sign_extend * buf[i] = temp8byte - * elif nBytes == 7: # <<<<<<<<<<<<<< + * elif n_bytes == 7: # <<<<<<<<<<<<<< * if swap == 0: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ goto __pyx_L3; } /* "dataRead.pyx":636 - * temp8byte |= signExtend + * temp8byte |= sign_extend * buf[i] = temp8byte - * elif nBytes == 6: # <<<<<<<<<<<<<< + * elif n_bytes == 6: # <<<<<<<<<<<<<< * if swap == 0: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ - __pyx_t_6 = ((__pyx_v_nBytes == 6) != 0); + __pyx_t_6 = ((__pyx_v_n_bytes == 6) != 0); if (__pyx_t_6) { /* "dataRead.pyx":637 * buf[i] = temp8byte - * elif nBytes == 6: + * elif n_bytes == 6: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":638 - * elif nBytes == 6: + * elif n_bytes == 6: * if swap == 0: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift */ - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":639 * if swap == 0: - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ - (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":641 - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":642 * # right shift - * if bitOffset > 0: - * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp8byte = temp8byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 48: + * if bit_count < 48: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); + __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bit_offset); /* "dataRead.pyx":641 - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":644 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 48: # <<<<<<<<<<<<<< + * if bit_count < 48: # <<<<<<<<<<<<<< * temp8byte &= mask - * signBit = temp8byte & signBitMask + * sign_bit = temp8byte & sign_bit_mask */ - __pyx_t_6 = ((__pyx_v_bitCount < 48) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 48) != 0); if (__pyx_t_6) { /* "dataRead.pyx":645 * # mask left part - * if bitCount < 48: + * if bit_count < 48: * temp8byte &= mask # <<<<<<<<<<<<<< - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); /* "dataRead.pyx":644 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 48: # <<<<<<<<<<<<<< + * if bit_count < 48: # <<<<<<<<<<<<<< * temp8byte &= mask - * signBit = temp8byte & signBitMask + * sign_bit = temp8byte & sign_bit_mask */ } /* "dataRead.pyx":646 - * if bitCount < 48: + * if bit_count < 48: * temp8byte &= mask - * signBit = temp8byte & signBitMask # <<<<<<<<<<<<<< - * if signBit: # negative value, sign extend - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask # <<<<<<<<<<<<<< + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend */ - __pyx_v_signBit = (__pyx_v_temp8byte & __pyx_v_signBitMask); + __pyx_v_sign_bit = (__pyx_v_temp8byte & __pyx_v_sign_bit_mask); /* "dataRead.pyx":647 * temp8byte &= mask - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp8byte |= sign_extend * buf[i] = temp8byte */ - __pyx_t_6 = (__pyx_v_signBit != 0); + __pyx_t_6 = (__pyx_v_sign_bit != 0); if (__pyx_t_6) { /* "dataRead.pyx":648 - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend - * temp8byte |= signExtend # <<<<<<<<<<<<<< + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend # <<<<<<<<<<<<<< * buf[i] = temp8byte * else: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_signExtend); + __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_sign_extend); /* "dataRead.pyx":647 * temp8byte &= mask - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp8byte |= sign_extend * buf[i] = temp8byte */ } /* "dataRead.pyx":649 - * if signBit: # negative value, sign extend - * temp8byte |= signExtend + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend * buf[i] = temp8byte # <<<<<<<<<<<<<< * else: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ __pyx_t_16 = __pyx_v_i; __pyx_t_11 = -1; @@ -9451,10 +9466,10 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ /* "dataRead.pyx":637 * buf[i] = temp8byte - * elif nBytes == 6: + * elif n_bytes == 6: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ goto __pyx_L29; } @@ -9462,132 +9477,132 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ /* "dataRead.pyx":651 * buf[i] = temp8byte * else: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp6, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp6, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp8byte = temp6[0]<<40 | temp6[1]<<32 | temp6[2]<<24 | \ */ /*else*/ { - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":652 * else: - * for i in range(numberOfRecords): - * memcpy(&temp6, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp6, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * temp8byte = temp6[0]<<40 | temp6[1]<<32 | temp6[2]<<24 | \ * temp6[3]<<16 | temp6[4]<<8 | temp6[5] # swap bytes */ - (void)(memcpy((&__pyx_v_temp6), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp6), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":654 - * memcpy(&temp6, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp6, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp8byte = temp6[0]<<40 | temp6[1]<<32 | temp6[2]<<24 | \ * temp6[3]<<16 | temp6[4]<<8 | temp6[5] # swap bytes # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ __pyx_v_temp8byte = (((((((__pyx_v_temp6[0]) << 40) | ((__pyx_v_temp6[1]) << 32)) | ((__pyx_v_temp6[2]) << 24)) | ((__pyx_v_temp6[3]) << 16)) | ((__pyx_v_temp6[4]) << 8)) | (__pyx_v_temp6[5])); /* "dataRead.pyx":656 * temp6[3]<<16 | temp6[4]<<8 | temp6[5] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":657 * # right shift - * if bitOffset > 0: - * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp8byte = temp8byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 48: + * if bit_count < 48: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); + __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bit_offset); /* "dataRead.pyx":656 * temp6[3]<<16 | temp6[4]<<8 | temp6[5] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":659 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 48: # <<<<<<<<<<<<<< + * if bit_count < 48: # <<<<<<<<<<<<<< * temp8byte &= mask - * signBit = temp8byte & signBitMask + * sign_bit = temp8byte & sign_bit_mask */ - __pyx_t_6 = ((__pyx_v_bitCount < 48) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 48) != 0); if (__pyx_t_6) { /* "dataRead.pyx":660 * # mask left part - * if bitCount < 48: + * if bit_count < 48: * temp8byte &= mask # <<<<<<<<<<<<<< - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); /* "dataRead.pyx":659 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 48: # <<<<<<<<<<<<<< + * if bit_count < 48: # <<<<<<<<<<<<<< * temp8byte &= mask - * signBit = temp8byte & signBitMask + * sign_bit = temp8byte & sign_bit_mask */ } /* "dataRead.pyx":661 - * if bitCount < 48: + * if bit_count < 48: * temp8byte &= mask - * signBit = temp8byte & signBitMask # <<<<<<<<<<<<<< - * if signBit: # negative value, sign extend - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask # <<<<<<<<<<<<<< + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend */ - __pyx_v_signBit = (__pyx_v_temp8byte & __pyx_v_signBitMask); + __pyx_v_sign_bit = (__pyx_v_temp8byte & __pyx_v_sign_bit_mask); /* "dataRead.pyx":662 * temp8byte &= mask - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp8byte |= sign_extend * buf[i] = temp8byte */ - __pyx_t_6 = (__pyx_v_signBit != 0); + __pyx_t_6 = (__pyx_v_sign_bit != 0); if (__pyx_t_6) { /* "dataRead.pyx":663 - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend - * temp8byte |= signExtend # <<<<<<<<<<<<<< + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend # <<<<<<<<<<<<<< * buf[i] = temp8byte - * elif nBytes == 5: + * elif n_bytes == 5: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_signExtend); + __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_sign_extend); /* "dataRead.pyx":662 * temp8byte &= mask - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp8byte |= sign_extend * buf[i] = temp8byte */ } /* "dataRead.pyx":664 - * if signBit: # negative value, sign extend - * temp8byte |= signExtend + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend * buf[i] = temp8byte # <<<<<<<<<<<<<< - * elif nBytes == 5: + * elif n_bytes == 5: * if swap == 0: */ __pyx_t_17 = __pyx_v_i; @@ -9603,155 +9618,155 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_L29:; /* "dataRead.pyx":636 - * temp8byte |= signExtend + * temp8byte |= sign_extend * buf[i] = temp8byte - * elif nBytes == 6: # <<<<<<<<<<<<<< + * elif n_bytes == 6: # <<<<<<<<<<<<<< * if swap == 0: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ goto __pyx_L3; } /* "dataRead.pyx":665 - * temp8byte |= signExtend + * temp8byte |= sign_extend * buf[i] = temp8byte - * elif nBytes == 5: # <<<<<<<<<<<<<< + * elif n_bytes == 5: # <<<<<<<<<<<<<< * if swap == 0: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ - __pyx_t_6 = ((__pyx_v_nBytes == 5) != 0); + __pyx_t_6 = ((__pyx_v_n_bytes == 5) != 0); if (__pyx_t_6) { /* "dataRead.pyx":666 * buf[i] = temp8byte - * elif nBytes == 5: + * elif n_bytes == 5: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ __pyx_t_6 = ((__pyx_v_swap == 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":667 - * elif nBytes == 5: + * elif n_bytes == 5: * if swap == 0: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift */ - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":668 * if swap == 0: - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ - (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp8byte), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":670 - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":671 * # right shift - * if bitOffset > 0: - * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp8byte = temp8byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 40: + * if bit_count < 40: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); + __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bit_offset); /* "dataRead.pyx":670 - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":673 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 40: # <<<<<<<<<<<<<< + * if bit_count < 40: # <<<<<<<<<<<<<< * temp8byte &= mask - * signBit = temp8byte & signBitMask + * sign_bit = temp8byte & sign_bit_mask */ - __pyx_t_6 = ((__pyx_v_bitCount < 40) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 40) != 0); if (__pyx_t_6) { /* "dataRead.pyx":674 * # mask left part - * if bitCount < 40: + * if bit_count < 40: * temp8byte &= mask # <<<<<<<<<<<<<< - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); /* "dataRead.pyx":673 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 40: # <<<<<<<<<<<<<< + * if bit_count < 40: # <<<<<<<<<<<<<< * temp8byte &= mask - * signBit = temp8byte & signBitMask + * sign_bit = temp8byte & sign_bit_mask */ } /* "dataRead.pyx":675 - * if bitCount < 40: + * if bit_count < 40: * temp8byte &= mask - * signBit = temp8byte & signBitMask # <<<<<<<<<<<<<< - * if signBit: # negative value, sign extend - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask # <<<<<<<<<<<<<< + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend */ - __pyx_v_signBit = (__pyx_v_temp8byte & __pyx_v_signBitMask); + __pyx_v_sign_bit = (__pyx_v_temp8byte & __pyx_v_sign_bit_mask); /* "dataRead.pyx":676 * temp8byte &= mask - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp8byte |= sign_extend * buf[i] = temp8byte */ - __pyx_t_6 = (__pyx_v_signBit != 0); + __pyx_t_6 = (__pyx_v_sign_bit != 0); if (__pyx_t_6) { /* "dataRead.pyx":677 - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend - * temp8byte |= signExtend # <<<<<<<<<<<<<< + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend # <<<<<<<<<<<<<< * buf[i] = temp8byte * else: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_signExtend); + __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_sign_extend); /* "dataRead.pyx":676 * temp8byte &= mask - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp8byte |= sign_extend * buf[i] = temp8byte */ } /* "dataRead.pyx":678 - * if signBit: # negative value, sign extend - * temp8byte |= signExtend + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend * buf[i] = temp8byte # <<<<<<<<<<<<<< * else: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ __pyx_t_18 = __pyx_v_i; __pyx_t_11 = -1; @@ -9765,10 +9780,10 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ /* "dataRead.pyx":666 * buf[i] = temp8byte - * elif nBytes == 5: + * elif n_bytes == 5: * if swap == 0: # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * memcpy(&temp8byte, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): + * memcpy(&temp8byte, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) */ goto __pyx_L40; } @@ -9776,130 +9791,130 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ /* "dataRead.pyx":680 * buf[i] = temp8byte * else: - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * memcpy(&temp5, &bita[posByteBeg + record_byte_size * i], nBytes) + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * memcpy(&temp5, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp8byte = temp5[0]<<32 | temp5[1]<<24 | \ */ /*else*/ { - __pyx_t_7 = __pyx_v_numberOfRecords; + __pyx_t_7 = __pyx_v_number_of_records; __pyx_t_8 = __pyx_t_7; for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_8; __pyx_t_9+=1) { __pyx_v_i = __pyx_t_9; /* "dataRead.pyx":681 * else: - * for i in range(numberOfRecords): - * memcpy(&temp5, &bita[posByteBeg + record_byte_size * i], nBytes) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * memcpy(&temp5, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) # <<<<<<<<<<<<<< * temp8byte = temp5[0]<<32 | temp5[1]<<24 | \ * temp5[2]<<16 | temp5[3]<<8 | temp5[4] # swap bytes */ - (void)(memcpy((&__pyx_v_temp5), (&(__pyx_v_bita[(__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_nBytes)); + (void)(memcpy((&__pyx_v_temp5), (&(__pyx_v_bit_stream[(__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))])), __pyx_v_n_bytes)); /* "dataRead.pyx":683 - * memcpy(&temp5, &bita[posByteBeg + record_byte_size * i], nBytes) + * memcpy(&temp5, &bit_stream[pos_byte_beg + record_byte_size * i], n_bytes) * temp8byte = temp5[0]<<32 | temp5[1]<<24 | \ * temp5[2]<<16 | temp5[3]<<8 | temp5[4] # swap bytes # <<<<<<<<<<<<<< * # right shift - * if bitOffset > 0: + * if bit_offset > 0: */ __pyx_v_temp8byte = ((((((__pyx_v_temp5[0]) << 32) | ((__pyx_v_temp5[1]) << 24)) | ((__pyx_v_temp5[2]) << 16)) | ((__pyx_v_temp5[3]) << 8)) | (__pyx_v_temp5[4])); /* "dataRead.pyx":685 * temp5[2]<<16 | temp5[3]<<8 | temp5[4] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ - __pyx_t_6 = ((__pyx_v_bitOffset > 0) != 0); + __pyx_t_6 = ((__pyx_v_bit_offset > 0) != 0); if (__pyx_t_6) { /* "dataRead.pyx":686 * # right shift - * if bitOffset > 0: - * temp8byte = temp8byte >> bitOffset # <<<<<<<<<<<<<< + * if bit_offset > 0: + * temp8byte = temp8byte >> bit_offset # <<<<<<<<<<<<<< * # mask left part - * if bitCount < 40: + * if bit_count < 40: */ - __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bitOffset); + __pyx_v_temp8byte = (__pyx_v_temp8byte >> __pyx_v_bit_offset); /* "dataRead.pyx":685 * temp5[2]<<16 | temp5[3]<<8 | temp5[4] # swap bytes * # right shift - * if bitOffset > 0: # <<<<<<<<<<<<<< - * temp8byte = temp8byte >> bitOffset + * if bit_offset > 0: # <<<<<<<<<<<<<< + * temp8byte = temp8byte >> bit_offset * # mask left part */ } /* "dataRead.pyx":688 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 40: # <<<<<<<<<<<<<< + * if bit_count < 40: # <<<<<<<<<<<<<< * temp8byte &= mask - * signBit = temp8byte & signBitMask + * sign_bit = temp8byte & sign_bit_mask */ - __pyx_t_6 = ((__pyx_v_bitCount < 40) != 0); + __pyx_t_6 = ((__pyx_v_bit_count < 40) != 0); if (__pyx_t_6) { /* "dataRead.pyx":689 * # mask left part - * if bitCount < 40: + * if bit_count < 40: * temp8byte &= mask # <<<<<<<<<<<<<< - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend */ __pyx_v_temp8byte = (__pyx_v_temp8byte & __pyx_v_mask); /* "dataRead.pyx":688 - * temp8byte = temp8byte >> bitOffset + * temp8byte = temp8byte >> bit_offset * # mask left part - * if bitCount < 40: # <<<<<<<<<<<<<< + * if bit_count < 40: # <<<<<<<<<<<<<< * temp8byte &= mask - * signBit = temp8byte & signBitMask + * sign_bit = temp8byte & sign_bit_mask */ } /* "dataRead.pyx":690 - * if bitCount < 40: + * if bit_count < 40: * temp8byte &= mask - * signBit = temp8byte & signBitMask # <<<<<<<<<<<<<< - * if signBit: # negative value, sign extend - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask # <<<<<<<<<<<<<< + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend */ - __pyx_v_signBit = (__pyx_v_temp8byte & __pyx_v_signBitMask); + __pyx_v_sign_bit = (__pyx_v_temp8byte & __pyx_v_sign_bit_mask); /* "dataRead.pyx":691 * temp8byte &= mask - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp8byte |= sign_extend * buf[i] = temp8byte */ - __pyx_t_6 = (__pyx_v_signBit != 0); + __pyx_t_6 = (__pyx_v_sign_bit != 0); if (__pyx_t_6) { /* "dataRead.pyx":692 - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend - * temp8byte |= signExtend # <<<<<<<<<<<<<< + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend # <<<<<<<<<<<<<< * buf[i] = temp8byte * return buf */ - __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_signExtend); + __pyx_v_temp8byte = (__pyx_v_temp8byte | __pyx_v_sign_extend); /* "dataRead.pyx":691 * temp8byte &= mask - * signBit = temp8byte & signBitMask - * if signBit: # negative value, sign extend # <<<<<<<<<<<<<< - * temp8byte |= signExtend + * sign_bit = temp8byte & sign_bit_mask + * if sign_bit: # negative value, sign extend # <<<<<<<<<<<<<< + * temp8byte |= sign_extend * buf[i] = temp8byte */ } /* "dataRead.pyx":693 - * if signBit: # negative value, sign extend - * temp8byte |= signExtend + * if sign_bit: # negative value, sign extend + * temp8byte |= sign_extend * buf[i] = temp8byte # <<<<<<<<<<<<<< * return buf * @@ -9917,21 +9932,21 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __pyx_L40:; /* "dataRead.pyx":665 - * temp8byte |= signExtend + * temp8byte |= sign_extend * buf[i] = temp8byte - * elif nBytes == 5: # <<<<<<<<<<<<<< + * elif n_bytes == 5: # <<<<<<<<<<<<<< * if swap == 0: - * for i in range(numberOfRecords): + * for i in range(number_of_records): */ } __pyx_L3:; /* "dataRead.pyx":694 - * temp8byte |= signExtend + * temp8byte |= sign_extend * buf[i] = temp8byte * return buf # <<<<<<<<<<<<<< * - * cdef inline dataReadByte(const char* bita, str RecordFormat, unsigned long long numberOfRecords, + * cdef inline read_byte(const char* bit_stream, str record_format, unsigned long long number_of_records, */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject *)__pyx_v_buf)); @@ -9941,9 +9956,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ /* "dataRead.pyx":556 * return buf * - * cdef inline dataReadLongLong(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, - * unsigned long bitCount, unsigned char bitOffset, unsigned long nBytes, unsigned char swap): + * cdef inline read_signed_longlong(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, + * unsigned long bit_count, unsigned char bit_offset, unsigned long n_bytes, unsigned char swap): */ /* function exit code */ @@ -9958,7 +9973,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb); __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_buf.rcbuffer->pybuffer); __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);} - __Pyx_AddTraceback("dataRead.dataReadLongLong", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("dataRead.read_signed_longlong", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; goto __pyx_L2; __pyx_L0:; @@ -9973,15 +9988,15 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadLongLong(char const *__ /* "dataRead.pyx":696 * return buf * - * cdef inline dataReadByte(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, unsigned long nBytes, - * unsigned long bitCount, unsigned char bitOffset): + * cdef inline read_byte(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, unsigned long n_bytes, + * unsigned long bit_count, unsigned char bit_offset): */ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadByte(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_nBytes, CYTHON_UNUSED unsigned long __pyx_v_bitCount, CYTHON_UNUSED unsigned char __pyx_v_bitOffset) { +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_byte(char const *__pyx_v_bit_stream, PyObject *__pyx_v_record_format, unsigned PY_LONG_LONG __pyx_v_number_of_records, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_pos_byte_beg, unsigned long __pyx_v_n_bytes, CYTHON_UNUSED unsigned long __pyx_v_bit_count, CYTHON_UNUSED unsigned char __pyx_v_bit_offset) { PyArrayObject *__pyx_v_buf = 0; unsigned PY_LONG_LONG __pyx_v_i; - unsigned long __pyx_v_posByteEnd; + unsigned long __pyx_v_pos_byte_end; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; @@ -9991,21 +10006,21 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadByte(char const *__pyx_ unsigned PY_LONG_LONG __pyx_t_5; unsigned PY_LONG_LONG __pyx_t_6; unsigned PY_LONG_LONG __pyx_t_7; - __Pyx_RefNannySetupContext("dataReadByte", 0); + __Pyx_RefNannySetupContext("read_byte", 0); /* "dataRead.pyx":699 - * unsigned long record_byte_size, unsigned long posByteBeg, unsigned long nBytes, - * unsigned long bitCount, unsigned char bitOffset): - * cdef np.ndarray buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, unsigned long n_bytes, + * unsigned long bit_count, unsigned char bit_offset): + * cdef np.ndarray buf = np.empty(number_of_records, dtype=record_format) # return numpy array # <<<<<<<<<<<<<< * cdef unsigned long long i - * cdef unsigned long posByteEnd = posByteBeg + nBytes + * cdef unsigned long pos_byte_end = pos_byte_beg + n_bytes */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 699, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 699, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_numberOfRecords); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 699, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_number_of_records); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 699, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 699, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); @@ -10014,7 +10029,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadByte(char const *__pyx_ __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 699, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 699, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_record_format) < 0) __PYX_ERR(0, 699, __pyx_L1_error) __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 699, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; @@ -10025,34 +10040,34 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadByte(char const *__pyx_ __pyx_t_4 = 0; /* "dataRead.pyx":701 - * cdef np.ndarray buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array + * cdef np.ndarray buf = np.empty(number_of_records, dtype=record_format) # return numpy array * cdef unsigned long long i - * cdef unsigned long posByteEnd = posByteBeg + nBytes # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * buf[i] = bytes(bita[posByteBeg + record_byte_size * i:\ + * cdef unsigned long pos_byte_end = pos_byte_beg + n_bytes # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * buf[i] = bytes(bit_stream[pos_byte_beg + record_byte_size * i:\ */ - __pyx_v_posByteEnd = (__pyx_v_posByteBeg + __pyx_v_nBytes); + __pyx_v_pos_byte_end = (__pyx_v_pos_byte_beg + __pyx_v_n_bytes); /* "dataRead.pyx":702 * cdef unsigned long long i - * cdef unsigned long posByteEnd = posByteBeg + nBytes - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * buf[i] = bytes(bita[posByteBeg + record_byte_size * i:\ - * posByteEnd + record_byte_size * i]) + * cdef unsigned long pos_byte_end = pos_byte_beg + n_bytes + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * buf[i] = bytes(bit_stream[pos_byte_beg + record_byte_size * i:\ + * pos_byte_end + record_byte_size * i]) */ - __pyx_t_5 = __pyx_v_numberOfRecords; + __pyx_t_5 = __pyx_v_number_of_records; __pyx_t_6 = __pyx_t_5; for (__pyx_t_7 = 0; __pyx_t_7 < __pyx_t_6; __pyx_t_7+=1) { __pyx_v_i = __pyx_t_7; /* "dataRead.pyx":703 - * cdef unsigned long posByteEnd = posByteBeg + nBytes - * for i in range(numberOfRecords): - * buf[i] = bytes(bita[posByteBeg + record_byte_size * i:\ # <<<<<<<<<<<<<< - * posByteEnd + record_byte_size * i]) + * cdef unsigned long pos_byte_end = pos_byte_beg + n_bytes + * for i in range(number_of_records): + * buf[i] = bytes(bit_stream[pos_byte_beg + record_byte_size * i:\ # <<<<<<<<<<<<<< + * pos_byte_end + record_byte_size * i]) * return buf */ - __pyx_t_4 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_bita + (__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i)), (__pyx_v_posByteEnd + (__pyx_v_record_byte_size * __pyx_v_i)) - (__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 703, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_bit_stream + (__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i)), (__pyx_v_pos_byte_end + (__pyx_v_record_byte_size * __pyx_v_i)) - (__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 703, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __pyx_t_1 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyBytes_Type)), __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 703, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); @@ -10062,11 +10077,11 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadByte(char const *__pyx_ } /* "dataRead.pyx":705 - * buf[i] = bytes(bita[posByteBeg + record_byte_size * i:\ - * posByteEnd + record_byte_size * i]) + * buf[i] = bytes(bit_stream[pos_byte_beg + record_byte_size * i:\ + * pos_byte_end + record_byte_size * i]) * return buf # <<<<<<<<<<<<<< * - * cdef inline dataReadArray(const char* bita, str RecordFormat, unsigned long long numberOfRecords, + * cdef inline read_array(const char* bit_stream, str record_format, unsigned long long number_of_records, */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(((PyObject *)__pyx_v_buf)); @@ -10076,9 +10091,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadByte(char const *__pyx_ /* "dataRead.pyx":696 * return buf * - * cdef inline dataReadByte(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, unsigned long nBytes, - * unsigned long bitCount, unsigned char bitOffset): + * cdef inline read_byte(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, unsigned long n_bytes, + * unsigned long bit_count, unsigned char bit_offset): */ /* function exit code */ @@ -10087,7 +10102,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadByte(char const *__pyx_ __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); - __Pyx_AddTraceback("dataRead.dataReadByte", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("dataRead.read_byte", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_buf); @@ -10099,15 +10114,15 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadByte(char const *__pyx_ /* "dataRead.pyx":707 * return buf * - * cdef inline dataReadArray(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, unsigned long nBytes, - * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): + * cdef inline read_array(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, unsigned long n_bytes, + * unsigned long bit_count, unsigned char bit_offset, unsigned char swap): */ -static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *__pyx_v_bita, PyObject *__pyx_v_RecordFormat, unsigned PY_LONG_LONG __pyx_v_numberOfRecords, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_posByteBeg, unsigned long __pyx_v_nBytes, CYTHON_UNUSED unsigned long __pyx_v_bitCount, CYTHON_UNUSED unsigned char __pyx_v_bitOffset, unsigned char __pyx_v_swap) { +static CYTHON_INLINE PyObject *__pyx_f_8dataRead_read_array(char const *__pyx_v_bit_stream, PyObject *__pyx_v_record_format, unsigned PY_LONG_LONG __pyx_v_number_of_records, unsigned long __pyx_v_record_byte_size, unsigned long __pyx_v_pos_byte_beg, unsigned long __pyx_v_n_bytes, CYTHON_UNUSED unsigned long __pyx_v_bit_count, CYTHON_UNUSED unsigned char __pyx_v_bit_offset, unsigned char __pyx_v_swap) { PyArrayObject *__pyx_v_buf = 0; unsigned PY_LONG_LONG __pyx_v_i; - unsigned long __pyx_v_posByteEnd; + unsigned long __pyx_v_pos_byte_end; PyObject *__pyx_r = NULL; __Pyx_RefNannyDeclarations PyObject *__pyx_t_1 = NULL; @@ -10118,21 +10133,21 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *__pyx unsigned PY_LONG_LONG __pyx_t_6; unsigned PY_LONG_LONG __pyx_t_7; int __pyx_t_8; - __Pyx_RefNannySetupContext("dataReadArray", 0); + __Pyx_RefNannySetupContext("read_array", 0); /* "dataRead.pyx":710 - * unsigned long record_byte_size, unsigned long posByteBeg, unsigned long nBytes, - * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): - * cdef np.ndarray buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, unsigned long n_bytes, + * unsigned long bit_count, unsigned char bit_offset, unsigned char swap): + * cdef np.ndarray buf = np.empty(number_of_records, dtype=record_format) # return numpy array # <<<<<<<<<<<<<< * cdef unsigned long long i - * cdef unsigned long posByteEnd = posByteBeg + nBytes + * cdef unsigned long pos_byte_end = pos_byte_beg + n_bytes */ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 710, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 710, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_numberOfRecords); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 710, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_number_of_records); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 710, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 710, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); @@ -10141,7 +10156,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *__pyx __pyx_t_1 = 0; __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 710, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 710, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_record_format) < 0) __PYX_ERR(0, 710, __pyx_L1_error) __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 710, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; @@ -10152,31 +10167,31 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *__pyx __pyx_t_4 = 0; /* "dataRead.pyx":712 - * cdef np.ndarray buf = np.empty(numberOfRecords, dtype=RecordFormat) # return numpy array + * cdef np.ndarray buf = np.empty(number_of_records, dtype=record_format) # return numpy array * cdef unsigned long long i - * cdef unsigned long posByteEnd = posByteBeg + nBytes # <<<<<<<<<<<<<< - * for i in range(numberOfRecords): - * buf[i] = np.fromstring(bita[posByteBeg + record_byte_size * i:\ + * cdef unsigned long pos_byte_end = pos_byte_beg + n_bytes # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * buf[i] = np.fromstring(bit_stream[pos_byte_beg + record_byte_size * i:\ */ - __pyx_v_posByteEnd = (__pyx_v_posByteBeg + __pyx_v_nBytes); + __pyx_v_pos_byte_end = (__pyx_v_pos_byte_beg + __pyx_v_n_bytes); /* "dataRead.pyx":713 * cdef unsigned long long i - * cdef unsigned long posByteEnd = posByteBeg + nBytes - * for i in range(numberOfRecords): # <<<<<<<<<<<<<< - * buf[i] = np.fromstring(bita[posByteBeg + record_byte_size * i:\ - * posByteEnd + record_byte_size * i], dtype=RecordFormat) + * cdef unsigned long pos_byte_end = pos_byte_beg + n_bytes + * for i in range(number_of_records): # <<<<<<<<<<<<<< + * buf[i] = np.fromstring(bit_stream[pos_byte_beg + record_byte_size * i:\ + * pos_byte_end + record_byte_size * i], dtype=record_format) */ - __pyx_t_5 = __pyx_v_numberOfRecords; + __pyx_t_5 = __pyx_v_number_of_records; __pyx_t_6 = __pyx_t_5; for (__pyx_t_7 = 0; __pyx_t_7 < __pyx_t_6; __pyx_t_7+=1) { __pyx_v_i = __pyx_t_7; /* "dataRead.pyx":714 - * cdef unsigned long posByteEnd = posByteBeg + nBytes - * for i in range(numberOfRecords): - * buf[i] = np.fromstring(bita[posByteBeg + record_byte_size * i:\ # <<<<<<<<<<<<<< - * posByteEnd + record_byte_size * i], dtype=RecordFormat) + * cdef unsigned long pos_byte_end = pos_byte_beg + n_bytes + * for i in range(number_of_records): + * buf[i] = np.fromstring(bit_stream[pos_byte_beg + record_byte_size * i:\ # <<<<<<<<<<<<<< + * pos_byte_end + record_byte_size * i], dtype=record_format) * if swap == 0: */ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 714, __pyx_L1_error) @@ -10186,20 +10201,20 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *__pyx __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; /* "dataRead.pyx":715 - * for i in range(numberOfRecords): - * buf[i] = np.fromstring(bita[posByteBeg + record_byte_size * i:\ - * posByteEnd + record_byte_size * i], dtype=RecordFormat) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * buf[i] = np.fromstring(bit_stream[pos_byte_beg + record_byte_size * i:\ + * pos_byte_end + record_byte_size * i], dtype=record_format) # <<<<<<<<<<<<<< * if swap == 0: * return buf */ - __pyx_t_4 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_bita + (__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i)), (__pyx_v_posByteEnd + (__pyx_v_record_byte_size * __pyx_v_i)) - (__pyx_v_posByteBeg + (__pyx_v_record_byte_size * __pyx_v_i))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 714, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_bit_stream + (__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i)), (__pyx_v_pos_byte_end + (__pyx_v_record_byte_size * __pyx_v_i)) - (__pyx_v_pos_byte_beg + (__pyx_v_record_byte_size * __pyx_v_i))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 714, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); /* "dataRead.pyx":714 - * cdef unsigned long posByteEnd = posByteBeg + nBytes - * for i in range(numberOfRecords): - * buf[i] = np.fromstring(bita[posByteBeg + record_byte_size * i:\ # <<<<<<<<<<<<<< - * posByteEnd + record_byte_size * i], dtype=RecordFormat) + * cdef unsigned long pos_byte_end = pos_byte_beg + n_bytes + * for i in range(number_of_records): + * buf[i] = np.fromstring(bit_stream[pos_byte_beg + record_byte_size * i:\ # <<<<<<<<<<<<<< + * pos_byte_end + record_byte_size * i], dtype=record_format) * if swap == 0: */ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 714, __pyx_L1_error) @@ -10209,21 +10224,21 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *__pyx __pyx_t_4 = 0; /* "dataRead.pyx":715 - * for i in range(numberOfRecords): - * buf[i] = np.fromstring(bita[posByteBeg + record_byte_size * i:\ - * posByteEnd + record_byte_size * i], dtype=RecordFormat) # <<<<<<<<<<<<<< + * for i in range(number_of_records): + * buf[i] = np.fromstring(bit_stream[pos_byte_beg + record_byte_size * i:\ + * pos_byte_end + record_byte_size * i], dtype=record_format) # <<<<<<<<<<<<<< * if swap == 0: * return buf */ __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 715, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_v_RecordFormat) < 0) __PYX_ERR(0, 715, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_v_record_format) < 0) __PYX_ERR(0, 715, __pyx_L1_error) /* "dataRead.pyx":714 - * cdef unsigned long posByteEnd = posByteBeg + nBytes - * for i in range(numberOfRecords): - * buf[i] = np.fromstring(bita[posByteBeg + record_byte_size * i:\ # <<<<<<<<<<<<<< - * posByteEnd + record_byte_size * i], dtype=RecordFormat) + * cdef unsigned long pos_byte_end = pos_byte_beg + n_bytes + * for i in range(number_of_records): + * buf[i] = np.fromstring(bit_stream[pos_byte_beg + record_byte_size * i:\ # <<<<<<<<<<<<<< + * pos_byte_end + record_byte_size * i], dtype=record_format) * if swap == 0: */ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 714, __pyx_L1_error) @@ -10236,8 +10251,8 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *__pyx } /* "dataRead.pyx":716 - * buf[i] = np.fromstring(bita[posByteBeg + record_byte_size * i:\ - * posByteEnd + record_byte_size * i], dtype=RecordFormat) + * buf[i] = np.fromstring(bit_stream[pos_byte_beg + record_byte_size * i:\ + * pos_byte_end + record_byte_size * i], dtype=record_format) * if swap == 0: # <<<<<<<<<<<<<< * return buf * else: @@ -10246,7 +10261,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *__pyx if (__pyx_t_8) { /* "dataRead.pyx":717 - * posByteEnd + record_byte_size * i], dtype=RecordFormat) + * pos_byte_end + record_byte_size * i], dtype=record_format) * if swap == 0: * return buf # <<<<<<<<<<<<<< * else: @@ -10258,8 +10273,8 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *__pyx goto __pyx_L0; /* "dataRead.pyx":716 - * buf[i] = np.fromstring(bita[posByteBeg + record_byte_size * i:\ - * posByteEnd + record_byte_size * i], dtype=RecordFormat) + * buf[i] = np.fromstring(bit_stream[pos_byte_beg + record_byte_size * i:\ + * pos_byte_end + record_byte_size * i], dtype=record_format) * if swap == 0: # <<<<<<<<<<<<<< * return buf * else: @@ -10301,9 +10316,9 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *__pyx /* "dataRead.pyx":707 * return buf * - * cdef inline dataReadArray(const char* bita, str RecordFormat, unsigned long long numberOfRecords, # <<<<<<<<<<<<<< - * unsigned long record_byte_size, unsigned long posByteBeg, unsigned long nBytes, - * unsigned long bitCount, unsigned char bitOffset, unsigned char swap): + * cdef inline read_array(const char* bit_stream, str record_format, unsigned long long number_of_records, # <<<<<<<<<<<<<< + * unsigned long record_byte_size, unsigned long pos_byte_beg, unsigned long n_bytes, + * unsigned long bit_count, unsigned char bit_offset, unsigned char swap): */ /* function exit code */ @@ -10312,7 +10327,7 @@ static CYTHON_INLINE PyObject *__pyx_f_8dataRead_dataReadArray(char const *__pyx __Pyx_XDECREF(__pyx_t_2); __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); - __Pyx_AddTraceback("dataRead.dataReadArray", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_AddTraceback("dataRead.read_array", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = 0; __pyx_L0:; __Pyx_XDECREF((PyObject *)__pyx_v_buf); @@ -12824,39 +12839,40 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = { {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0}, {&__pyx_n_s_ImportError, __pyx_k_ImportError, sizeof(__pyx_k_ImportError), 0, 0, 1, 1}, {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0}, - {&__pyx_n_s_RecordFormat, __pyx_k_RecordFormat, sizeof(__pyx_k_RecordFormat), 0, 0, 1, 1}, {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1}, {&__pyx_n_s_S, __pyx_k_S, sizeof(__pyx_k_S), 0, 0, 1, 1}, {&__pyx_n_s_V, __pyx_k_V, sizeof(__pyx_k_V), 0, 0, 1, 1}, {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1}, {&__pyx_n_s_array, __pyx_k_array, sizeof(__pyx_k_array), 0, 0, 1, 1}, {&__pyx_n_s_big, __pyx_k_big, sizeof(__pyx_k_big), 0, 0, 1, 1}, - {&__pyx_n_s_bitCount, __pyx_k_bitCount, sizeof(__pyx_k_bitCount), 0, 0, 1, 1}, - {&__pyx_n_s_bitOffset, __pyx_k_bitOffset, sizeof(__pyx_k_bitOffset), 0, 0, 1, 1}, - {&__pyx_n_s_bita, __pyx_k_bita, sizeof(__pyx_k_bita), 0, 0, 1, 1}, + {&__pyx_n_s_bit_count, __pyx_k_bit_count, sizeof(__pyx_k_bit_count), 0, 0, 1, 1}, + {&__pyx_n_s_bit_offset, __pyx_k_bit_offset, sizeof(__pyx_k_bit_offset), 0, 0, 1, 1}, + {&__pyx_n_s_bit_stream, __pyx_k_bit_stream, sizeof(__pyx_k_bit_stream), 0, 0, 1, 1}, {&__pyx_n_s_byteorder, __pyx_k_byteorder, sizeof(__pyx_k_byteorder), 0, 0, 1, 1}, {&__pyx_n_s_byteswap, __pyx_k_byteswap, sizeof(__pyx_k_byteswap), 0, 0, 1, 1}, {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, {&__pyx_n_s_dataRead, __pyx_k_dataRead, sizeof(__pyx_k_dataRead), 0, 0, 1, 1}, {&__pyx_kp_s_dataRead_pyx, __pyx_k_dataRead_pyx, sizeof(__pyx_k_dataRead_pyx), 0, 0, 1, 0}, + {&__pyx_n_s_data_read, __pyx_k_data_read, sizeof(__pyx_k_data_read), 0, 0, 1, 1}, {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1}, {&__pyx_n_s_empty, __pyx_k_empty, sizeof(__pyx_k_empty), 0, 0, 1, 1}, {&__pyx_n_s_fromstring, __pyx_k_fromstring, sizeof(__pyx_k_fromstring), 0, 0, 1, 1}, {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, {&__pyx_n_s_little, __pyx_k_little, sizeof(__pyx_k_little), 0, 0, 1, 1}, {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, - {&__pyx_n_s_nBytes, __pyx_k_nBytes, sizeof(__pyx_k_nBytes), 0, 0, 1, 1}, + {&__pyx_n_s_n_bytes, __pyx_k_n_bytes, sizeof(__pyx_k_n_bytes), 0, 0, 1, 1}, {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0}, {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0}, {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1}, - {&__pyx_n_s_numberOfRecords, __pyx_k_numberOfRecords, sizeof(__pyx_k_numberOfRecords), 0, 0, 1, 1}, + {&__pyx_n_s_number_of_records, __pyx_k_number_of_records, sizeof(__pyx_k_number_of_records), 0, 0, 1, 1}, {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1}, {&__pyx_kp_s_numpy_core_multiarray_failed_to, __pyx_k_numpy_core_multiarray_failed_to, sizeof(__pyx_k_numpy_core_multiarray_failed_to), 0, 0, 1, 0}, {&__pyx_kp_s_numpy_core_umath_failed_to_impor, __pyx_k_numpy_core_umath_failed_to_impor, sizeof(__pyx_k_numpy_core_umath_failed_to_impor), 0, 0, 1, 0}, - {&__pyx_n_s_posByteBeg, __pyx_k_posByteBeg, sizeof(__pyx_k_posByteBeg), 0, 0, 1, 1}, + {&__pyx_n_s_pos_byte_beg, __pyx_k_pos_byte_beg, sizeof(__pyx_k_pos_byte_beg), 0, 0, 1, 1}, {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, {&__pyx_n_s_record_byte_size, __pyx_k_record_byte_size, sizeof(__pyx_k_record_byte_size), 0, 0, 1, 1}, - {&__pyx_n_s_signalDataType, __pyx_k_signalDataType, sizeof(__pyx_k_signalDataType), 0, 0, 1, 1}, + {&__pyx_n_s_record_format, __pyx_k_record_format, sizeof(__pyx_k_record_format), 0, 0, 1, 1}, + {&__pyx_n_s_signal_data_type, __pyx_k_signal_data_type, sizeof(__pyx_k_signal_data_type), 0, 0, 1, 1}, {&__pyx_n_s_sys, __pyx_k_sys, sizeof(__pyx_k_sys), 0, 0, 1, 1}, {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, {&__pyx_n_s_tmp, __pyx_k_tmp, sizeof(__pyx_k_tmp), 0, 0, 1, 1}, @@ -12977,14 +12993,14 @@ static int __Pyx_InitCachedConstants(void) { /* "dataRead.pyx":11 * #@cython.boundscheck(False) * #@cython.wraparound(False) - * def dataRead(bytes tmp, unsigned short bitCount, # <<<<<<<<<<<<<< - * unsigned short signalDataType, str RecordFormat, unsigned long long numberOfRecords, - * unsigned long record_byte_size, unsigned char bitOffset, + * def data_read(bytes tmp, unsigned short bit_count, # <<<<<<<<<<<<<< + * unsigned short signal_data_type, str record_format, unsigned long long number_of_records, + * unsigned long record_byte_size, unsigned char bit_offset, */ - __pyx_tuple__10 = PyTuple_Pack(11, __pyx_n_s_tmp, __pyx_n_s_bitCount, __pyx_n_s_signalDataType, __pyx_n_s_RecordFormat, __pyx_n_s_numberOfRecords, __pyx_n_s_record_byte_size, __pyx_n_s_bitOffset, __pyx_n_s_posByteBeg, __pyx_n_s_nBytes, __pyx_n_s_array, __pyx_n_s_bita); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(0, 11, __pyx_L1_error) + __pyx_tuple__10 = PyTuple_Pack(11, __pyx_n_s_tmp, __pyx_n_s_bit_count, __pyx_n_s_signal_data_type, __pyx_n_s_record_format, __pyx_n_s_number_of_records, __pyx_n_s_record_byte_size, __pyx_n_s_bit_offset, __pyx_n_s_pos_byte_beg, __pyx_n_s_n_bytes, __pyx_n_s_array, __pyx_n_s_bit_stream); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(0, 11, __pyx_L1_error) __Pyx_GOTREF(__pyx_tuple__10); __Pyx_GIVEREF(__pyx_tuple__10); - __pyx_codeobj__11 = (PyObject*)__Pyx_PyCode_New(10, 0, 11, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__10, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_dataRead_pyx, __pyx_n_s_dataRead, 11, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__11)) __PYX_ERR(0, 11, __pyx_L1_error) + __pyx_codeobj__11 = (PyObject*)__Pyx_PyCode_New(10, 0, 11, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__10, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_dataRead_pyx, __pyx_n_s_data_read, 11, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__11)) __PYX_ERR(0, 11, __pyx_L1_error) __Pyx_RefNannyFinishContext(); return 0; __pyx_L1_error:; @@ -13286,13 +13302,13 @@ if (!__Pyx_RefNanny) { /* "dataRead.pyx":11 * #@cython.boundscheck(False) * #@cython.wraparound(False) - * def dataRead(bytes tmp, unsigned short bitCount, # <<<<<<<<<<<<<< - * unsigned short signalDataType, str RecordFormat, unsigned long long numberOfRecords, - * unsigned long record_byte_size, unsigned char bitOffset, + * def data_read(bytes tmp, unsigned short bit_count, # <<<<<<<<<<<<<< + * unsigned short signal_data_type, str record_format, unsigned long long number_of_records, + * unsigned long record_byte_size, unsigned char bit_offset, */ - __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_8dataRead_1dataRead, NULL, __pyx_n_s_dataRead); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 11, __pyx_L1_error) + __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_8dataRead_1data_read, NULL, __pyx_n_s_dataRead); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 11, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - if (PyDict_SetItem(__pyx_d, __pyx_n_s_dataRead, __pyx_t_2) < 0) __PYX_ERR(0, 11, __pyx_L1_error) + if (PyDict_SetItem(__pyx_d, __pyx_n_s_data_read, __pyx_t_2) < 0) __PYX_ERR(0, 11, __pyx_L1_error) __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "dataRead.pyx":1 diff --git a/mdfreader/mdf.py b/mdfreader/mdf.py index 391a5a2..b8b2858 100644 --- a/mdfreader/mdf.py +++ b/mdfreader/mdf.py @@ -120,8 +120,10 @@ def __init__(self, file_name=None, channel_list=None, convert_after_read=True, filter_channel_names : bool, optional flag to filter long channel names from its module names separated by '.' + compression : bool optional flag to compress data in memory + convert_tables : bool, optional, default False flag to convert or not only conversions with tables. These conversions types take generally long time and memory @@ -299,6 +301,7 @@ def _remove_channel_field(self, channel_name, field): channel name field : str channel dict key + Returns ------- removed value from dict @@ -416,6 +419,7 @@ def _get_channel_field(self, channel_name, field=None): channel name field : str channel dict key + Returns ------- channel description string @@ -504,7 +508,7 @@ def set_channel_conversion(self, channel_name, conversion): channel_name : str channel name conversion : dict - conversion dictionnary + conversion dictionary """ self._set_channel(channel_name, conversion, field=conversionField) @@ -521,6 +525,18 @@ def set_channel_attachment(self, channel_name, attachment): self._set_channel(channel_name, attachment, field=attachmentField) def set_invalid_bit(self, channel_name, bit_position): + """returns the invalid bit position of channel + + Parameters + ---------------- + channel_name : str + channel name + bit_position + invalid bit position of channel within invalid channel bytes + Returns + ------- + bit position + """ self[channel_name][invalidPosField] = bit_position def set_invalid_channel(self, channel_name, invalid_channel): @@ -551,7 +567,7 @@ def _channel_in_mdf(self, channel_name): channel_name : str channel name - Return + Returns ------- bool """ @@ -573,7 +589,7 @@ def add_metadata(self, author='', organisation='', project='', date : str time : str - Note + Notes ===== All fields are optional, default being empty string """ @@ -591,9 +607,9 @@ def __str__(self): Returns ------------ string of mdf class ordered as below - master_channel_name + "master_channel_name channel_name description - numpy_array unit + numpy_array unit" """ output = list() if self.fileName is not None: @@ -785,8 +801,6 @@ def __init__(self): ------------- data : numpy array compressed compressed data - size : tuple - numpy array size dtype : numpy dtype object numpy array dtype """ @@ -807,7 +821,7 @@ def compression(self, a): def decompression(self): """ data decompression - Return + Returns ------------- uncompressed numpy array """ diff --git a/mdfreader/mdf3reader.py b/mdfreader/mdf3reader.py index fb03605..45565a6 100644 --- a/mdfreader/mdf3reader.py +++ b/mdfreader/mdf3reader.py @@ -596,8 +596,8 @@ def read_record_bits(self, bit_stream, channel_set=None): """ from bitarray import bitarray - B = bitarray(endian="little") # little endian by default - B.frombytes(bytes(bit_stream)) + bit_array = bitarray(endian="little") # little endian by default + bit_array.frombytes(bytes(bit_stream)) def signed_int(temp, extension): """ extend bits of signed data managing two's complement @@ -619,15 +619,15 @@ def signed_int(temp, extension): channel_set = self.channelNames for Channel in self: # list of channel classes from channelSet if Channel.name in channel_set: - temp[Channel.name] = B[Channel.posBitBeg: Channel.posBitEnd] + temp[Channel.name] = bit_array[Channel.posBitBeg: Channel.posBitEnd] n_bytes = len(temp[Channel.name].tobytes()) if not n_bytes == Channel.nBytes: - byte = bitarray(8 * (Channel.nBytes - n_bytes), endian='little') - byte.setall(False) + delta_byte = bitarray(8 * (Channel.nBytes - n_bytes), endian='little') + delta_byte.setall(False) if Channel.signalDataType not in (1, 10, 14): # not signed integer - temp[Channel.name].extend(byte) + temp[Channel.name].extend(delta_byte) else: # signed integer (two's complement), keep sign bit and extend with bytes - temp[Channel.name] = signed_int(temp[Channel.name], byte) + temp[Channel.name] = signed_int(temp[Channel.name], delta_byte) n_trail_bits = Channel.nBytes*8 - Channel.bitCount if Channel.signalDataType in (1, 10, 14) and \ n_bytes == Channel.nBytes and \ @@ -734,8 +734,6 @@ def load_unsorted(self, name_list=None): Parameters ---------------- - record: class - channel group definition listing record channel classes name_list : set of str, optional list of channel names diff --git a/mdfreader/mdf4reader.py b/mdfreader/mdf4reader.py index a140767..6abb4ac 100644 --- a/mdfreader/mdf4reader.py +++ b/mdfreader/mdf4reader.py @@ -112,8 +112,8 @@ def _data_block(record, info, parent_block, channel_set=None, n_records=None, so return _read_unsorted(record, info, parent_block, channel_set) elif parent_block['id'] in ('##SD', b'##SD'): - return _read_sdblock(record[record.VLSD[0]].signal_data_type(info), parent_block['data'], - parent_block['length'] - 24) + return _read_sd_block(record[record.VLSD[0]].signal_data_type(info), parent_block['data'], + parent_block['length'] - 24) elif parent_block['id'] in ('##DZ', b'##DZ'): # zipped data block # uncompress data @@ -121,8 +121,8 @@ def _data_block(record, info, parent_block, channel_set=None, n_records=None, so parent_block['dz_zip_parameter'], parent_block['dz_org_data_length']) if vlsd: # VLSD channel - return _read_sdblock(record[record.VLSD[0]].signal_data_type(info), parent_block['data'], - parent_block['dz_org_data_length']) + return _read_sd_block(record[record.VLSD[0]].signal_data_type(info), parent_block['data'], + parent_block['dz_org_data_length']) if channel_set is None and sorted_flag: # reads all blocks if sorted block and no channelSet defined if record.byte_aligned and not record.hiddenBytes: return fromstring(parent_block['data'], dtype={'names': record.dataRecordName, @@ -137,7 +137,29 @@ def _data_block(record, info, parent_block, channel_set=None, n_records=None, so def _read_unsorted(record, info, parent_block, channel_set=None): - # reads only the channels using offset functions, channel by channel. + """ reads only the channels using offset functions, channel by channel within unsorted data + + Parameters + ------------ + record : class + record class + info: info class + channel_set : set of str, optional + set of channel to read + parent_block: + number of records + channel_set: set + set of channel names to be parsed + + Returns + -------- + buf : array + data array + + Notes + ------ + channel_set is not used yet + """ buf = defaultdict(list) position = 0 record_id_c_format = record[list(record.keys())[0]]['record'].recordIDCFormat @@ -146,8 +168,7 @@ def _read_unsorted(record, info, parent_block, channel_set=None): # initialise data structure for record_id in record: for channelName in record[record_id]['record'].dataRecordName: - buf[channelName] = [] # empty(record.numberOfRecords,dtype=record[recordID]['record'].dataFormat) - # index[channelName]=0 + buf[channelName] = [] # read data while position < len(parent_block['data']): record_id = record_id_c_format.unpack(parent_block['data'][position:position + record_id_size])[0] @@ -179,22 +200,22 @@ def _read_unsorted(record, info, parent_block, channel_set=None): return buf -def _read_sdblock(signal_data_type, sdblock, sdblock_length): +def _read_sd_block(signal_data_type, sd_block, sd_block_length): """ Reads vlsd channel from its SD Block bytes - Parameters - ---------------- - signal_data_type : int + Parameters + ---------------- + signal_data_type : int - sdblock : bytes - SD Block bytes + sd_block : bytes + SD Block bytes - sdblock_length: int - SD Block data length (header not included) + sd_block_length: int + SD Block data length (header not included) - Returns - ----------- - array + Returns + ----------- + array """ if signal_data_type == 6: channel_format = 'ISO8859' @@ -207,10 +228,10 @@ def _read_sdblock(signal_data_type, sdblock, sdblock_length): pointer = 0 buf = [] - while pointer < sdblock_length: - VLSDLen = structunpack('I', sdblock[pointer:pointer + 4])[0] # length of data + while pointer < sd_block_length: + VLSDLen = structunpack('I', sd_block[pointer:pointer + 4])[0] # length of data pointer += 4 - buf.append(sdblock[pointer:pointer + VLSDLen].decode(channel_format).rstrip('\x00')) + buf.append(sd_block[pointer:pointer + VLSDLen].decode(channel_format).rstrip('\x00')) pointer += VLSDLen buf = _equalize_string_length(buf) return array(buf) @@ -575,7 +596,7 @@ def __str__(self): output.append('CG {} '.format(chan.channelGroup)) output.append('CN {} '.format(chan.channelNumber)) output.append('VLSD {} \n'.format(chan.VLSD_CG_Flag)) - output.append('CG block record bytes length : {}\nDatagroup number : {}' + output.append('CG block record bytes length : {}\nData group number : {}' '\nByte aligned : {}\nHidden bytes : {}\n'.format(self.CGrecordLength, self.dataGroup, self.byte_aligned, self.hiddenBytes)) if self.master['name'] is not None: @@ -595,8 +616,8 @@ def add_channel(self, info, channel_number): channel_number : int channel number in mdfinfo4.info4 class """ - Channel = Channel4() - self.append(Channel.set(info, self.dataGroup, self.channelGroup, channel_number)) + channel = Channel4() + self.append(channel.set(info, self.dataGroup, self.channelGroup, channel_number)) self.channelNames.add(self[-1].name) def load_info(self, info): @@ -959,7 +980,7 @@ def read_channels_from_bytes(self, bit_stream, info, channel_set=None, n_records buf = recarray(n_records, dtype=dtype) if buf is not None: # at least some channels should be parsed if dataRead_available: # use rather cython compiled code for performance - bytesdata = bytes(bit_stream) + bytes_data = bytes(bit_stream) for chan in channels_indexes: if self[chan].is_ca_block(info): ca = self[chan].ca_block(info) @@ -967,7 +988,7 @@ def read_channels_from_bytes(self, bit_stream, info, channel_set=None, n_records else: array_flag = 0 buf[self[chan].name] = \ - data_read(bytesdata, self[chan].bit_count(info), + data_read(bytes_data, self[chan].bit_count(info), self[chan].signal_data_type(info), self[chan].native_data_format(info), n_records, self.CGrecordLength, @@ -1025,45 +1046,45 @@ def signed_int(temp, extension): if buf is not None: # read data from bitarray import bitarray - B = bitarray(endian="little") # little endian by default - B.frombytes(bytes(bit_stream)) + bit_array = bitarray(endian="little") # little endian by default + bit_array.frombytes(bytes(bit_stream)) record_bit_size = self.CGrecordLength * 8 for chan in channels_indexes: - signal_data_type = self[chan].signalDataType(info) - n_bytes = self[chan].nBytes + signal_data_type = self[chan].signal_data_type(info) + n_bytes_estimated = self[chan].nBytes if not self[chan].type in (1, 2): - temp = [B[self[chan].posBitBeg(info) + record_bit_size * i: - self[chan].posBitEnd(info) + record_bit_size * i] + temp = [bit_array[self[chan].pos_bit_beg(info) + record_bit_size * i: + self[chan].pos_bit_end(info) + record_bit_size * i] for i in range(n_records)] - nbytes = len(temp[0].tobytes()) - if not nbytes == n_bytes and \ + n_bytes = len(temp[0].tobytes()) + if not n_bytes == n_bytes_estimated and \ signal_data_type not in (6, 7, 8, 9, 10, 11, 12): # not Ctype byte length - byte = bitarray(8 * (n_bytes - nbytes), endian='little') + byte = bitarray(8 * (n_bytes_estimated - n_bytes), endian='little') byte.setall(False) if signal_data_type not in (2, 3): # not signed integer for i in range(n_records): # extend data of bytes to match numpy requirement temp[i].extend(byte) else: # signed integer (two's complement), keep sign bit and extend with bytes temp = signed_int(temp, byte) - n_trail_bits = n_bytes*8 - self[chan].bitCount(info) + n_trail_bits = n_bytes_estimated*8 - self[chan].bit_count(info) if signal_data_type in (2, 3) and \ - nbytes == n_bytes and \ - n_trail_bits > 0: # Ctype byte length but signed integer + n_bytes == n_bytes_estimated and \ + n_trail_bits > 0: # C type byte length but signed integer trail_bits = bitarray(n_trail_bits, endian='little') temp = signed_int(temp, trail_bits) else: # Channel Array - temp = [B[self[chan].posBitBeg(info) + record_bit_size * i: - self[chan].posBitBeg(info) + 8 * n_bytes + record_bit_size * i] + temp = [bit_array[self[chan].pos_bit_beg(info) + record_bit_size * i: + self[chan].pos_bit_beg(info) + 8 * n_bytes_estimated + record_bit_size * i] for i in range(n_records)] - if 's' not in self[chan].Format(info): - CFormat = self[chan].CFormat(info) - if ('>' in self[chan].dataFormat(info) and byteorder == 'little') or \ - (byteorder == 'big' and '<' in self[chan].dataFormat(info)): - temp = [CFormat.unpack(temp[i].tobytes())[0] + if 's' not in self[chan].c_format(info): + c_structure = self[chan].c_format_structure(info) + if ('>' in self[chan].data_format(info) and byteorder == 'little') or \ + (byteorder == 'big' and '<' in self[chan].data_format(info)): + temp = [c_structure.unpack(temp[i].tobytes())[0] for i in range(n_records)] temp = asarray(temp).byteswap().newbyteorder() else: - temp = [CFormat.unpack(temp[i].tobytes())[0] + temp = [c_structure.unpack(temp[i].tobytes())[0] for i in range(n_records)] temp = asarray(temp) else: @@ -1366,10 +1387,10 @@ def returnField(obj, field): if convert_after_read and not compression: self._noDataLoading = False - self._convert_all_channel_4() + self._convert_all_channel4() # print( 'Finished in ' + str( time.clock() - inttime ) , file=stderr) - def _get_channel_data_4(self, channel_name, raw_data=False): + def _get_channel_data4(self, channel_name, raw_data=False): """Returns channel numpy array Parameters @@ -1395,15 +1416,15 @@ def _get_channel_data_4(self, channel_name, raw_data=False): (self.info.fid, self.info.fileName, self.info.zipfile) = _open_mdf(self.fileName) self.read4(file_name=None, info=None, channel_list=[channel_name], convert_after_read=False) if not raw_data: - return self._convert_channel_data_4(self.get_channel(channel_name), - channel_name, self.convertTables)[channel_name] + return self._convert_channel_data4(self.get_channel(channel_name), channel_name, + self.convertTables)[channel_name] else: return self.get_channel(channel_name)[dataField] else: return None @staticmethod - def _convert_channel_data_4(channel, channel_name, convert_tables, multi_processed=False, q=None): + def _convert_channel_data4(channel, channel_name, convert_tables, multi_processed=False, q=None): """converts specific channel from raw to physical data according to CCBlock information Parameters @@ -1449,12 +1470,14 @@ def _convert_channel_data_4(channel, channel_name, convert_tables, multi_process elif conversion_type == 6 and not text_type and convert_tables: vector = _value_range_to_value_table_conversion(vector, conversion_parameter['cc_val']) elif conversion_type == 7 and not text_type and convert_tables: - vector = _value_to_text_conversion(vector, conversion_parameter['cc_val'], conversion_parameter['cc_ref']) + vector = _value_to_text_conversion(vector, conversion_parameter['cc_val'], + conversion_parameter['cc_ref']) elif conversion_type == 8 and not text_type and convert_tables: vector = _value_range_to_text_conversion(vector, conversion_parameter['cc_val'], conversion_parameter['cc_ref']) elif conversion_type == 9 and text_type and convert_tables: - vector = _text_to_value_conversion(vector, conversion_parameter['cc_val'], conversion_parameter['cc_ref']) + vector = _text_to_value_conversion(vector, conversion_parameter['cc_val'], + conversion_parameter['cc_ref']) elif conversion_type == 10 and text_type and convert_tables: vector = _text_to_text_conversion(vector, conversion_parameter['cc_ref']) L = dict() @@ -1464,7 +1487,7 @@ def _convert_channel_data_4(channel, channel_name, convert_tables, multi_process else: return L - def _convert_channel_4(self, channel_name): + def _convert_channel4(self, channel_name): """converts specific channel from raw to physical data according to CCBlock information Parameters @@ -1472,10 +1495,10 @@ def _convert_channel_4(self, channel_name): channel_name : str Name of channel """ - self.set_channel_data(channel_name, self._get_channel_data_4(channel_name)) + self.set_channel_data(channel_name, self._get_channel_data4(channel_name)) self.remove_channel_conversion(channel_name) - def _convert_all_channel_4(self): + def _convert_all_channel4(self): """Converts all channels from raw data to converted data according to CCBlock information Converted data will take more memory. """ @@ -1484,7 +1507,7 @@ def _convert_all_channel_4(self): self.read4(self.fileName, convert_after_read=True) else: if self.multiProc is False: - [self._convert_channel_4(channelName) for channelName in self] + [self._convert_channel4(channelName) for channelName in self] else: # multiprocessing proc = [] Q = Queue() @@ -1494,9 +1517,9 @@ def _convert_all_channel_4(self): if 'conversion' in channel: conversion = self.get_channel_conversion(channelName) if conversion['type'] in (1, 2): # more time in multi proc - self._convert_channel_4(channelName) + self._convert_channel4(channelName) else: - proc.append(Process(target=self._convert_channel_data_4, + proc.append(Process(target=self._convert_channel_data4, args=(channel, channelName, self.convertTables, True, Q))) proc[-1].start() for p in proc: @@ -1584,13 +1607,13 @@ def write4(self, file_name=None, compression=False): pointer = blocks['CG']['block_start'] + 104 blocks['CG']['CN'] = pointer # First CN link - master_channel_data = self._get_channel_data_4(masterChannel) + master_channel_data = self._get_channel_data4(masterChannel) if master_channel_data is not None: cg_cycle_count = len(master_channel_data) - elif self._get_channel_data_4(self.masterChannelList[masterChannel][0]).shape[0] == 1: # classification + elif self._get_channel_data4(self.masterChannelList[masterChannel][0]).shape[0] == 1: # classification cg_cycle_count = 1 elif master_channel_data not in self.masterChannelList[masterChannel]: - cg_cycle_count = len(self._get_channel_data_4(self.masterChannelList[masterChannel][0])) + cg_cycle_count = len(self._get_channel_data4(self.masterChannelList[masterChannel][0])) warn('no master channel in data group {}'.format(dataGroup)) else: # no data in data group, skip @@ -1773,8 +1796,8 @@ def apply_invalid_bit(self, channel_name): try: invalid_bit_pos = self.get_invalid_bit(channel_name) if isinstance(invalid_bit_pos, int): # invalid bit existing - mask = self._get_channel_data_4(self.get_invalid_channel(channel_name)) - data = self._get_channel_data_4(channel_name) + mask = self._get_channel_data4(self.get_invalid_channel(channel_name)) + data = self._get_channel_data4(channel_name) data = data.view(MaskedArray) invalid_byte = invalid_bit_pos >> 3 data.mask = bitwise_and(mask[:, invalid_byte], invalid_bit_pos & 0x07) @@ -1943,13 +1966,13 @@ def _value_range_to_value_table_conversion(vector, cc_val): key_max = [cc_val[i] for i in range(1, 3 * val_count + 1, 3)] value = [cc_val[i] for i in range(2, 3 * val_count + 1, 3)] # look up in range keys - for lindex in range(len(vector)): + for l_index in range(len(vector)): key_index = 0 # default index if not found for i in range(val_count): - if key_min[i] < vector[lindex] < key_max[i]: + if key_min[i] < vector[l_index] < key_max[i]: key_index = i break - vector[lindex] = value[key_index] + vector[l_index] = value[key_index] return vector @@ -2081,10 +2104,10 @@ def _text_to_value_conversion(vector, cc_val, cc_ref): """ ref_count = len(cc_ref) temp = [] - for lindex in range(len(vector)): + for l_index in range(len(vector)): key_index = ref_count # default index if not found for i in range(ref_count): - if vector[lindex] == cc_ref[i]: + if vector[l_index] == cc_ref[i]: key_index = i break temp.append(cc_val[key_index]) @@ -2105,11 +2128,11 @@ def _text_to_text_conversion(vector, cc_ref): converted data to physical value """ ref_count = len(cc_ref) - 2 - for lindex in range(len(vector)): + for l_index in range(len(vector)): key_index = ref_count + 1 # default index if not found for i in range(0, ref_count, 2): - if vector[lindex] == cc_ref[i]: + if vector[l_index] == cc_ref[i]: key_index = i break - vector[lindex] = cc_ref[key_index] + vector[l_index] = cc_ref[key_index] return vector diff --git a/mdfreader/mdfreader.py b/mdfreader/mdfreader.py index c8ae1a3..34b5898 100644 --- a/mdfreader/mdfreader.py +++ b/mdfreader/mdfreader.py @@ -192,7 +192,7 @@ def read_info(self, file_name=None, fid=None, minimal=0): self.update(Info3(None, self.fid, self.filterChannelNames)) else: # MDF version 4.x self.update(Info4(None, self.fid, minimal)) - if self.zipfile and fid is None: # not from mdfreader.read() + if self.zipfile and fid is None: # not from mdfreader.read() remove(self.fileName) def list_channels(self, file_name=None): @@ -396,8 +396,8 @@ def read(self, file_name=None, multi_processed=False, channel_list=None, convert if self.MDFVersionNumber < 400: # up to version 3.x not compatible with version 4.x if not no_data_loading: - self.read3(self.fileName, None, multi_processed, channel_list, convert_after_read, filter_channel_names, - compression) + self.read3(self.fileName, None, multi_processed, channel_list, + convert_after_read, filter_channel_names, compression) else: # populate minimum mdf structure self._noDataLoading = True self.info = Info3(None, fid=self.fid, minimal=1) @@ -405,7 +405,8 @@ def read(self, file_name=None, multi_processed=False, channel_list=None, convert self.update(mdf_dict) else: # MDF version 4.x if not no_data_loading: - self.read4(self.fileName, None, multi_processed, channel_list, convert_after_read, compression, metadata) + self.read4(self.fileName, None, multi_processed, channel_list, + convert_after_read, compression, metadata) else: # populate minimum mdf structure self._noDataLoading = True self.info = Info4(None, fid=self.fid, minimal=1) @@ -422,7 +423,8 @@ def write(self, file_name=None, compression=False): ---------------- file_name : str, optional Name of file - If file name is not input, written file name will be the one read with appended '_new' string before extension + If file name is not input, written file name will be the one read with + appended '_new' string before extension compression : bool Flag to store data compressed (from mdf version 4.1) If activated, will write in version 4.1 even if original file is in version 3.x @@ -465,7 +467,7 @@ def get_channel_data(self, channel_name, raw_data=False): if self.MDFVersionNumber < 400: vector = self._get_channel_data3(channel_name, raw_data) else: - vector = self._get_channel_data_4(channel_name, raw_data) + vector = self._get_channel_data4(channel_name, raw_data) if self._noDataLoading: # remove data loaded in object to save memory self.set_channel_data(channel_name, None) @@ -478,7 +480,7 @@ def convert_all_channels(self): if self.MDFVersionNumber < 400: return self._convert_all_channel3() else: - return self._convert_all_channel_4() + return self._convert_all_channel4() def plot(self, channel_name_list_of_list): """Plot channels with Matplotlib @@ -619,7 +621,8 @@ def interpolate(new_x, x, y): else: master_data = arange(min(min_time), max(max_time), sampling_time) self.add_channel(master_channel_name, master_data, master_channel_name, - master_type=self.get_channel_master_type(master), unit=self.get_channel_unit(master), + master_type=self.get_channel_master_type(master), + unit=self.get_channel_unit(master), description=self.get_channel_desc(master), conversion=None) else: master_channel_name = master_channel # master channel defined in argument @@ -632,7 +635,8 @@ def interpolate(new_x, x, y): # create master channel if not proposed if master_channel is None and master_data is not None: self.add_channel(master_channel_name, master_data, master_channel_name, - master_type=self.get_channel_master_type(master), unit=self.get_channel_unit(master), + master_type=self.get_channel_master_type(master), + unit=self.get_channel_unit(master), description=self.get_channel_desc(master), conversion=None) # Interpolate channels @@ -1353,10 +1357,10 @@ def convert_to_pandas(self, sampling=None): args = parser.parse_args() - temp = Mdf(fileName=args.fileName, channelList=args.channelList, - converAfterRead=args.convertAfterRead, - filterChannelNames=args.filterChannelNames, - noDataLoading=args.noDataLoading, + temp = Mdf(file_name=args.fileName, channel_list=args.channelList, + convert_after_read=args.convertAfterRead, + filter_channel_names=args.filterChannelNames, + no_data_loading=args.noDataLoading, compression=args.compression) if args.export is not None: if args.export == 'CSV': From 7ef391b51cbc86e188e2977e66f757d56336c55b Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Thu, 1 Nov 2018 18:40:32 +0100 Subject: [PATCH 48/61] added mpldatacursor as optional requirement --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index cd5e655..1636c9c 100644 --- a/setup.py +++ b/setup.py @@ -78,7 +78,7 @@ # $ pip install -e .[dev,test] extras_require = { 'export': ['scipy', 'h5py', 'xlwt', 'xlwt3', 'openpyxl>2.0', 'pandas'], - 'plot': ['matplotlib'], + 'plot': ['matplotlib', 'mpldatacursor'], 'converter': ['PyQt4'], 'experimental': ['bitarray'], 'compression': ['blosc'], From f261416b91578147f49add5aab9c369e0203f870 Mon Sep 17 00:00:00 2001 From: Aymeric Rateau Date: Thu, 1 Nov 2018 18:41:39 +0100 Subject: [PATCH 49/61] updated docs after further pep8 cleaning --- docs/mdfreader.pdf | Bin 222608 -> 222711 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/mdfreader.pdf b/docs/mdfreader.pdf index 448498e9305796fd72c7e2664993b09c00bc1b23..a6ce123928b6b738e9d6a09677acd9c97588e56b 100644 GIT binary patch delta 61281 zcmZs?V{~Ovx3ycboeC3Qif!Arvtv7{*tvDybH4B1+uHfHMw@H? zTx<5x`*>#D1k%$4QY{-gI4euyUrQ=rQ{06003)i{(`!UWW4@BP`0~I+3O`|_u*$VC z*08!XVNBV1#?^+RzmL$_)KAyqa}CK8u~h`f&XtU zZf`lApYYhq_&4SH)w*uU+WZ;cs2Wjnlr9NFn#drIMG?GI>DaYau0k|h97nN%dm^se z93}MlBc2;iBi=ey35AevkgLWC4(Q6^ja4FN%u>sLQO{#JX+%R2a6SVf15_|Vp>#6! z(adkzIg)(b99KD5x~fMsbA6#IWquvfI*8*DOos+yrT;zV#~$amNP0e+_j50Ic%VW_ zeg(5_HDiD`vom%6?PO+T`>#su#(-`x!~lHgjdfNk3rEFt9CU5PMa8!7O8c=tfQ!!s!vt)f zrGF)&1-75>q6L8a*H|QMpGpspulwb|?#~gM&uyiLb7K!~y=6W(g7O}Xn(}S=(r(3S z@;r`swQz=fO@G%rqSd_q)P`hK!^e%^=S@P2rgcyWDxI3)4;oN-gb8G#6HM1)jyeuV z5rF~GuT(@>nTnEoYkT@A$O62`*fz>+3^w@_{u3lJKHfpQ4y;Rk>8JuY*R{#OZ^-o1 z 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