Skip to content

Commit

Permalink
Merge pull request #59 from evalott100/restore_enum_behaviour
Browse files Browse the repository at this point in the history
Allowed for empty tables to be parsed in table_to_words
  • Loading branch information
evalott100 authored Oct 16, 2023
2 parents 4cc1e30 + c4c787e commit 0226e54
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 5 deletions.
22 changes: 17 additions & 5 deletions pandablocks/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from pandablocks.responses import TableFieldInfo

UnpackedArray = Union[
npt.NDArray[np.uint8],
npt.NDArray[np.uint16],
npt.NDArray[np.int32],
npt.NDArray[np.uint32],
List[str],
Expand Down Expand Up @@ -55,16 +57,24 @@ def words_to_table(
# Mask to remove every bit that isn't in the range we want
mask = (1 << bit_length) - 1

value = (packed[word_offset] >> bit_offset) & mask
value: npt.NDArray[np.uint32] = (packed[word_offset] >> bit_offset) & mask
packing_value: UnpackedArray

if field_info.subtype == "int":
# First convert from 2's complement to offset, then add in offset.
packing_value = (value ^ (1 << (bit_length - 1))) + (-1 << (bit_length - 1))
temp = (value ^ (1 << (bit_length - 1))) + (-1 << (bit_length - 1))
packing_value = temp.astype(np.int32)
elif field_info.subtype == "enum" and convert_enum_indices:
assert field_info.labels, f"Enum field {field_name} has no labels"
packing_value = [field_info.labels[x] for x in value]
else:
packing_value = value
# Use shorter types, as these are used in waveform creation
if bit_length <= 8:
packing_value = value.astype(np.uint8)
elif bit_length <= 16:
packing_value = value.astype(np.uint16)
else:
packing_value = value.astype(np.uint32) # already uint32

unpacked.update({field_name: packing_value})

Expand Down Expand Up @@ -109,8 +119,10 @@ def table_to_words(
packed = np.zeros((len(column), row_words), dtype=np.uint32)
else:
assert len(packed) == len(column), (
f"Table record {column_name} has mismatched length "
"compared to other records, cannot pack data"
f"Table record {column_name} has mismatched length {len(column)} "
f"compared to other records {len(packed)}, cannot pack data. "
"If setting values through the ioc, ensure all values are given "
"before submitting."
)

offset = field_details.bit_low
Expand Down
16 changes: 16 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,3 +349,19 @@ def test_table_packing_pack(

for actual, expected in zip(unpacked, table_data_1):
assert actual == expected


def test_table_packing_give_default_values(
table_1_np_arrays: Dict[str, UnpackedArray],
table_field_info: TableFieldInfo,
):
# We should have a complete table at the point of unpacking
table_1_np_arrays["TRIGGER"] = np.array([])

try:
table_to_words(table_1_np_arrays, table_field_info)
except AssertionError as e:
assert (
"Table record TRIGGER has mismatched length 0 compared "
"to other records 3" in str(e)
)

0 comments on commit 0226e54

Please sign in to comment.