Skip to content

Commit 9f55f8b

Browse files
authored
Merge pull request #1 from harp-tech/gl-dev
Add single register binary file reader
2 parents e5b430f + a6465a8 commit 9f55f8b

1 file changed

Lines changed: 58 additions & 0 deletions

File tree

harp/io.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
from os import PathLike
2+
from typing import Any, Optional, Union
3+
from pandas._typing import Axes
4+
import numpy as np
5+
import pandas as pd
6+
7+
_SECONDS_PER_TICK = 32e6
8+
payloadtypes = {
9+
1: np.dtype(np.uint8),
10+
2: np.dtype(np.uint16),
11+
4: np.dtype(np.uint32),
12+
8: np.dtype(np.uint64),
13+
129: np.dtype(np.int8),
14+
130: np.dtype(np.int16),
15+
132: np.dtype(np.int32),
16+
136: np.dtype(np.int64),
17+
68: np.dtype(np.float32),
18+
}
19+
20+
21+
def read(
22+
file: Union[str, bytes, PathLike[Any], np._IOProtocol],
23+
columns: Optional[Axes] = None,
24+
):
25+
"""
26+
Read single-register Harp data from the specified file.
27+
28+
:param str file or str or Path: Open file object or filename containing
29+
binary data from a single device register.
30+
:param str or array-like names: The optional column labels to use for
31+
the data values.
32+
:return: A pandas data frame containing harp event data, sorted by time.
33+
"""
34+
data = np.fromfile(file, dtype=np.uint8)
35+
if len(data) == 0:
36+
return pd.DataFrame(
37+
columns=columns, index=pd.Index([], dtype=np.float64, name="time")
38+
)
39+
40+
stride = data[1] + 2
41+
length = len(data) // stride
42+
payloadsize = stride - 12
43+
payloadtype = payloadtypes[data[4] & ~0x10]
44+
elementsize = payloadtype.itemsize
45+
payloadshape = (length, payloadsize // elementsize)
46+
seconds = np.ndarray(length, dtype=np.uint32, buffer=data, offset=5, strides=stride)
47+
micros = np.ndarray(length, dtype=np.uint16, buffer=data, offset=9, strides=stride)
48+
seconds = micros * _SECONDS_PER_TICK + seconds
49+
payload = np.ndarray(
50+
payloadshape,
51+
dtype=payloadtype,
52+
buffer=data,
53+
offset=11,
54+
strides=(stride, elementsize),
55+
)
56+
time = pd.Series(seconds)
57+
time.name = "time"
58+
return pd.DataFrame(payload, index=time, columns=columns)

0 commit comments

Comments
 (0)