|
1 | 1 | import re |
2 | | -from functools import partial, reduce |
3 | | -from pandas import DataFrame |
4 | | -from typing import Iterable, Callable |
5 | | -from harp.model import Model, Register |
| 2 | +from functools import partial |
| 3 | +from pandas import DataFrame, Series |
| 4 | +from typing import Iterable, Callable, Union |
| 5 | +from harp.model import BitMask, GroupMask, MaskValueItem, Model, Register |
6 | 6 | from harp.io import read |
7 | 7 |
|
8 | 8 | _camel_to_snake_regex = re.compile(r"(?<!^)(?=[A-Z])") |
@@ -32,62 +32,78 @@ def __getattr__(self, __name: str) -> RegisterReader: |
32 | 32 | return self.registers[__name] |
33 | 33 |
|
34 | 34 |
|
35 | | -def compose(f, g): |
| 35 | +def _compose(f, g): |
36 | 36 | return lambda *a, **kw: f(g(*a, **kw)) |
37 | 37 |
|
38 | 38 |
|
39 | | -def id_camel_to_snake(id: str): |
| 39 | +def _id_camel_to_snake(id: str): |
40 | 40 | return _camel_to_snake_regex.sub("_", id).lower() |
41 | 41 |
|
42 | 42 |
|
43 | | -def keys_camel_to_snake(keys: Iterable[str]): |
44 | | - return [id_camel_to_snake(k) for k in keys] |
| 43 | +def _keys_camel_to_snake(keys: Iterable[str]): |
| 44 | + return [_id_camel_to_snake(k) for k in keys] |
45 | 45 |
|
46 | 46 |
|
47 | | -def create_bitreader(mask): |
48 | | - return lambda xs: ((xs & mask) != 0) |
| 47 | +def _create_bit_parser(mask: Union[int, MaskValueItem]): |
| 48 | + def parser(xs: Series) -> Series: |
| 49 | + return (xs & mask) != 0 |
49 | 50 |
|
| 51 | + return parser |
50 | 52 |
|
51 | | -def create_reader(device: Model): |
52 | | - reg_readers = { |
53 | | - name: create_register_reader(device, name) for name in device.registers.keys() |
54 | | - } |
55 | | - return DeviceReader(device, reg_readers) |
56 | 53 |
|
| 54 | +def _create_bitmask_parser(bitMask: BitMask): |
| 55 | + lookup = [ |
| 56 | + (_id_camel_to_snake(k), _create_bit_parser(v.root)) |
| 57 | + for k, v in bitMask.bits.items() |
| 58 | + ] |
| 59 | + |
| 60 | + def parser(df: DataFrame): |
| 61 | + return DataFrame({n: f(df[0]) for n, f in lookup}, index=df.index) |
| 62 | + |
| 63 | + return parser |
| 64 | + |
| 65 | + |
| 66 | +def _create_groupmask_parser(name: str, groupMask: GroupMask): |
| 67 | + name = _id_camel_to_snake(name) |
| 68 | + lookup = {v.root: n for n, v in groupMask.values.items()} |
| 69 | + |
| 70 | + def parser(df: DataFrame): |
| 71 | + return DataFrame({name: df.map(lambda x: lookup[x])}) |
| 72 | + |
| 73 | + return parser |
57 | 74 |
|
58 | | -def create_register_reader(device: Model, name: str): |
| 75 | + |
| 76 | +def _create_register_reader(device: Model, name: str): |
59 | 77 | register = device.registers[name] |
60 | 78 | reader = read |
61 | 79 |
|
62 | 80 | if register.maskType is not None: |
63 | 81 | key = register.maskType.root |
64 | 82 | bitMask = device.bitMasks.get(key) |
65 | 83 | if bitMask is not None: |
66 | | - lookup = [ |
67 | | - (id_camel_to_snake(k), create_bitreader(v.root)) |
68 | | - for k, v in bitMask.bits.items() |
69 | | - ] |
70 | | - |
71 | | - def unpack(df): |
72 | | - return DataFrame({n: f(df[0]) for n, f in lookup}, index=df.index) |
73 | | - |
74 | | - reader = compose(unpack, reader) |
| 84 | + parser = _create_bitmask_parser(bitMask) |
| 85 | + reader = _compose(parser, reader) |
75 | 86 | return RegisterReader(register, reader) |
76 | 87 |
|
77 | 88 | groupMask = device.groupMasks.get(key) |
78 | 89 | if groupMask is not None: |
79 | | - name = id_camel_to_snake(name) |
80 | | - lookup = {value.root: name for name, value in groupMask.values.items()} |
81 | | - reader = partial(reader, columns=[name]) |
82 | | - reader = compose(lambda df: df.map(lambda x: lookup[x]), reader) |
| 90 | + parser = _create_groupmask_parser(name, groupMask) |
| 91 | + reader = _compose(parser, reader) |
83 | 92 | return RegisterReader(register, reader) |
84 | 93 |
|
85 | 94 | if register.payloadSpec is not None: |
86 | 95 | columns = register.payloadSpec.keys() |
87 | | - columns = keys_camel_to_snake(columns) |
| 96 | + columns = _keys_camel_to_snake(columns) |
88 | 97 | reader = partial(reader, columns=columns) |
89 | 98 | return RegisterReader(register, reader) |
90 | 99 |
|
91 | | - columns = [id_camel_to_snake(name)] |
| 100 | + columns = [_id_camel_to_snake(name)] |
92 | 101 | reader = partial(reader, columns=columns) |
93 | 102 | return RegisterReader(register, reader) |
| 103 | + |
| 104 | + |
| 105 | +def create_reader(device: Model): |
| 106 | + reg_readers = { |
| 107 | + name: _create_register_reader(device, name) for name in device.registers.keys() |
| 108 | + } |
| 109 | + return DeviceReader(device, reg_readers) |
0 commit comments