Skip to main content

harp-data

Load Harp register data into pandas DataFrames. This is the package that pulls in pandas. harp-protocol stays numpy-only and exposes a pandas-free ColumnData view that this package assembles into a DataFrame.

There are two ways in, depending on what is on disk:

  • a whole dataset folder holding many registers, read with DatasetReader
  • a single register file or buffer, read with parse_to_dataframe

Read a whole dataset folder

A Harp acquisition is usually saved as a de-multiplexed folder, one binary file per register, named <DeviceName>_<address>.bin, alongside the device.yml schema for the device:

📦 session.harp
 ┣ 📜 Behavior_0.bin
 ┣ 📜 Behavior_44.bin
 ┣ ...
 ┗ 📜 device.yml

Reading is based on a device module that describes how to decode each register. open_dataset supplies one automatically. It finds the device.yml in the folder, builds the module, and returns a ready-to-use reader:

from harp import data

reader = data.open_dataset("session.harp")
df = reader.read("AnalogData")  # by name
df = reader.read(44)            # by address

contents maps every register with data in the folder to its address, keyed by register name. It is the place to start on an unfamiliar dataset, and since its keys are exactly what read takes, loading a whole dataset can be done with a comprehension:

reader.contents  # {'WhoAmI': 0, 'AnalogData': 33, ...}

frames = {name: reader.read(name) for name in reader.contents}

A name is resolved through the device register map rather than the module namespace, so the core registers are accessible by name too.

The schema describes the structure regardless of what was recorded. This means a register declared in the device register map with no data present in the folder reads as an empty DataFrame carrying the same columns. contents is what distinguishes the two cases. A register the device does not declare at all raises KeyError.

Given a device module already in hand, either a pre-generated package or one built with create_device_module, pass it as the second argument:

from harp import data
from harp.device import behavior

reader = data.open_dataset("session.harp", behavior)
df = reader.read(behavior.AnalogData)  # by register class

Prefer the register class where a generated package supplies one, since it is the only form that type-checks and a misspelling is caught before the folder is read. A module built by create_device_module resolves its registers as Any, so there the class verifies no more than the name does.

The Harp time becomes the DataFrame index named "Time", as float seconds by default or an absolute DatetimeIndex when the dataset is opened with epoch=REFERENCE_EPOCH. The anchor is set once for the dataset, since it describes how the recording was made rather than how one register is read. Data carrying no timestamp raise unless time_index=False is passed. Multi-chunk registers logged as <DeviceName>_<address>_<suffix>.bin are concatenated in filename order. Pass a resolver to support an alternative on-disk layout. paths reports what the resolver found, keyed by address, which is where a custom layout or a chunked register can be checked.

The <DeviceName> prefix comes from the DEVICE_NAME declared by the device module. Pass name= to override it, or to supply one when the module declares an empty name.

When a device module declaring an identity is supplied and the folder carries a device.yml, their whoAmI values are checked against each other. Reusing a module across sessions and opening the wrong folder then fails on construction rather than decoding the files against the wrong register map. Pass validate=False to turn off every check the reader performs, so a folder whose device.yml is damaged can be read with a module obtained elsewhere.

Read a single register file

parse_to_dataframe takes a register and a source, either a path, bytes, or an open binary file, and returns one row per frame:

from harp import data
from my_device import AnalogData

df = data.parse_to_dataframe(AnalogData, "AnalogData.bin")
df = data.parse_to_dataframe(
    AnalogData, raw, time_index=True, epoch=None, keep_type=False, decode_enums=True
)

time_index decides the index: True, the default, gives the Harp time named "Time", and False gives a RangeIndex. epoch anchors that index, giving float seconds when omitted and an absolute DatetimeIndex when set to a datetime such as REFERENCE_EPOCH. This function reads one file rather than a dataset, so it takes the anchor directly. Enum fields decode to pd.Categorical, and decode_enums=False keeps raw codes.

From an already-parsed payload

Given a batched payload already in hand, for example from register.parse_bulk, convert it directly:

from harp import data

_data, timestamps, _msg, payload = AnalogData.parse_bulk(raw)
df = data.payload_to_dataframe(payload)

Write data back out

to_file and to_buffer are the inverse of the readers, encoding values as Harp frames. Useful for round-tripping data or generating test corpora:

from harp import data

data.to_file(AnalogData, values, "AnalogData.bin", timestamps=seconds)

harp-data is released as open source under the MIT license. Bug reports and contributions are welcome at the GitHub repository.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

harp_data-0.5.0.tar.gz (13.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

harp_data-0.5.0-py3-none-any.whl (13.3 kB view details)

Uploaded Python 3

File details

Details for the file harp_data-0.5.0.tar.gz.

File metadata

  • Download URL: harp_data-0.5.0.tar.gz
  • Upload date:
  • Size: 13.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.6 {"installer":{"name":"uv","version":"0.12.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for harp_data-0.5.0.tar.gz
Algorithm Hash digest
SHA256 b2077b1db720b6f3a6a64dab505a220dee3325043160d55048668f43cd624901
MD5 44a3337504ec955181299b163341ee28
BLAKE2b-256 3502ed591b7f515b365d0acca9f4e37fa020db3bc8f083b8491fd1fbe5cd87f3

See more details on using hashes here.

File details

Details for the file harp_data-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: harp_data-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 13.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.6 {"installer":{"name":"uv","version":"0.12.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for harp_data-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e564c5cabd8a21cf9cb3cdcda58e0f271c25f3f7e4859e2a617a28c6f6296bac
MD5 5bfdedccf8ff2887c615427bf4ac0ebc
BLAKE2b-256 befefc5ea9da435b026c89f05a7fb381a26d4049a85509e982add63256da9505

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.5.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page