Skip to content

Commit

Permalink
Fix/pressure parser error (#17)
Browse files Browse the repository at this point in the history
* added an integration tests revealing parser bug

* Revert "Merge pull request #11 from MideTechnology/feature/10_parser-optimization"

This reverts commit a045a8e, reversing
changes made to aefe43d.

* Revert "Revert "Merge pull request #11 from MideTechnology/feature/10_parser-optimization""

This reverts commit aeff0ad.

The original reversion confirms that the issue is not related to
archive/#11; with that confirmed, the original reversion may be removed

* removed code causing deprecation warnings

* manually specified in numpy parser standardized mapping from struct to numpy typestrings

* added sanity checks for integrity of typestring conversions

* moved typestring assertion to unit tests
  • Loading branch information
CrepeGoat committed Oct 14, 2020
1 parent 5d9f5ef commit e7d8b68
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 6 deletions.
2 changes: 1 addition & 1 deletion idelib/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ def getExitCondition(recording, bytesRead=1000):
if idx <= len(data):
result = data[idx]
except (IOError, IndexError, ValueError) as e:
logger.warn(e)
logger.warning(e)

recording.seek(offset)
return result
37 changes: 32 additions & 5 deletions idelib/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,6 @@ def getHeader(self):


class ChannelDataArrayBlock(ChannelDataBlock):

def __init__(self, element):
super(ChannelDataArrayBlock, self).__init__(element)
self._payload = None
Expand All @@ -905,6 +904,34 @@ def payload(self):
self._payloadEl.gc()
return self._payload

# Define standard mapping from struct to numpy typestring
# (conversions taken from struct & numpy docs:)
# https://docs.python.org/3/library/struct.html#format-characters
# https://numpy.org/doc/stable/reference/arrays.dtypes.html#specifying-and-constructing-data-types
TO_NP_TYPESTR = {
# 'x': '',
'c': 'b',
'b': 'b',
'B': 'B',
'?': '?',
'h': 'i2',
'H': 'u2',
'i': 'i4',
'I': 'u4',
'l': 'i4',
'L': 'u4',
'q': 'i8',
'Q': 'u8',
# 'n': '',
# 'N': '',
# 'e': 'f2', unsupported in Python3.5
'f': 'f4',
'd': 'f8',
# 's': '',
# 'p': '',
# 'P': '',
}

def parseWith(self, parser, start=None, end=None, step=1, subchannel=None):
""" Parse an element's payload. Use this instead of directly using
`parser.parse()` for consistency's sake.
Expand Down Expand Up @@ -941,13 +968,13 @@ def parseWith(self, parser, start=None, end=None, step=1, subchannel=None):
else:
endian = '>'

streamDtype = np.dtype(
','.join([endian+typeId for typeId in parser_format])
)
streamDtype = np.dtype(','.join([
endian + self.TO_NP_TYPESTR[typeId] for typeId in parser_format
]))

isHomogeneous = len(set(parser_format)) == 1
if isHomogeneous:
commonDtype = np.dtype(endian + parser_format[0])
commonDtype = np.dtype(endian + self.TO_NP_TYPESTR[parser_format[0]])
else:
commonDtype = None

Expand Down
Binary file added testing/test3.IDE
Binary file not shown.
42 changes: 42 additions & 0 deletions testing/test_integration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import os.path

import pytest # type: ignore
import idelib


@pytest.mark.parametrize('filename', [
os.path.join('testing', 'test3.IDE'),
])
def test_integ_channels(filename):
with idelib.importFile(filename) as ds:
assert {i for i in ds.channels.keys()} == {8, 36, 59, 70, 80, 84}

accel100g_ch = ds.channels[8]
data = accel100g_ch.getSession().arraySlice()
assert data.shape[0] == 5 # t, x, y, z, mic
assert data.size > 0

accel40g_ch = ds.channels[80]
data = accel40g_ch.getSession().arraySlice()
assert data.shape[0] == 4 # t, x, y, z
assert data.size > 0

rot_ch = ds.channels[84]
data = rot_ch.getSession().arraySlice()
assert data.shape[0] == 4 # t, x, y, z
assert data.size > 0

orient_ch = ds.channels[70]
data = orient_ch.getSession().arraySlice()
assert data.shape[0] == 5 # t, x, y, z, w
assert data.size > 0

pt_ch = ds.channels[36]
data = pt_ch.getSession().arraySlice()
assert data.shape[0] == 3 # t, press, temp
assert data.size > 0

pt_ctrl_ch = ds.channels[59]
data = pt_ctrl_ch.getSession().arraySlice()
assert data.shape[0] == 3 # t, press, temp
assert data.size > 0
9 changes: 9 additions & 0 deletions testing/test_parsers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import unittest
import mock
import struct

from ebmlite.core import * # type: ignore
import numpy as np # type: ignore
Expand Down Expand Up @@ -107,6 +108,14 @@ def testParseMinMeanMax(self):
def testGetHeader(self):
self.assertEqual(self.block.getHeader(), (211, 32))

def testToNpTypestr(self):
for stype, nptype in ChannelDataArrayBlock.TO_NP_TYPESTR.items():
for endian in ('<', '>'):
assert (
struct.calcsize(endian+stype)
== np.dtype(endian+nptype).itemsize
)

def testParseWith(self):
parser = self.doc.channels[32].parser

Expand Down

0 comments on commit e7d8b68

Please sign in to comment.