Python interface and CLI for the Reiser Lab ArenaController.
Project description
arena-interface
arena-interface is a small typed Python package and CLI for controlling the
Reiser Lab ArenaController firmware over serial or Ethernet and for collecting
host-side benchmark results that can be compared with firmware-side PERF_* QS
records.
The distribution name is arena-interface and the import package is
arena_interface:
from arena_interface import ArenaInterface
Install
End users
Create a virtual environment and install from PyPI:
python -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install arena-interface
On Windows PowerShell:
py -m venv .venv
.\.venv\Scripts\Activate.ps1
py -m pip install --upgrade pip
py -m pip install arena-interface
Contributors
For local development without Pixi:
python -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
python -m pytest -q
If you use Pixi instead, run pixi install. Pixi will create or refresh
pixi.lock from pyproject.toml.
Quick start
Ethernet example
from arena_interface import ArenaInterface
ai = ArenaInterface(debug=True)
ai.set_ethernet_mode("192.168.10.104")
ai.all_on()
ai.all_off()
ai.switch_grayscale(1)
ai.set_refresh_rate(200)
stats = ai.get_perf_stats()
len(stats), stats.hex()[:64]
ai.show_pattern_frame(pattern_id=10, frame_index=0, frame_rate=200)
ai.update_pattern_frame(1)
ai.update_pattern_frame(2)
ai.all_off()
ai.close()
Serial example
from arena_interface import ArenaInterface
with ArenaInterface() as ai:
ai.set_serial_mode("/dev/ttyACM0")
ai.all_on()
ai.all_off()
On Windows, use a COM port such as COM3 instead of /dev/ttyACM0.
Command-line usage
The console entry point is arena-interface.
arena-interface --ethernet 192.168.10.104 all-on
arena-interface --ethernet 192.168.10.104 all-off
arena-interface --ethernet 192.168.10.104 set-refresh-rate 200
arena-interface --ethernet 192.168.10.104 switch-grayscale 1
arena-interface --ethernet 192.168.10.104 get-perf-stats
arena-interface --ethernet 192.168.10.104 reset-perf-stats
Serial examples:
arena-interface --serial /dev/ttyACM0 all-on
arena-interface --serial /dev/ttyACM0 all-off
PowerShell:
arena-interface --serial COM3 all-on
arena-interface --serial COM3 all-off
Environment-variable based usage
export ARENA_ETH_IP=192.168.10.104
arena-interface all-on
arena-interface all-off
arena-interface bench
PowerShell equivalent:
$env:ARENA_ETH_IP = "192.168.10.104"
arena-interface all-on
arena-interface all-off
arena-interface bench
Repository layout
This repository uses a modern src/ layout and a single pyproject.toml as
its packaging and tooling source of truth.
src/arena_interface/: importable package, version metadata, and CLItests/: lightweight tests that do not require hardwarescripts/: developer helper scripts, including benchmark matrix and performance summary helperstools/: repository-local helper tools such as the QSPY/QTools wrapperpatterns/: example pattern files for streaming tests.github/workflows/: CI and PyPI publishing automationpyproject.toml: package metadata, tool configuration, and Pixi manifestMANIFEST.in: explicit source-distribution file list for non-package assets
The package version lives in src/arena_interface/__about__.py; setuptools
reads that value dynamically so wheel, sdist, import metadata, and repository
metadata stay aligned.
Development workflow
Pixi
pixi install
pixi run help
pixi run version-show
pixi run check
pixi run release-check
pixi run qtools-install
pixi run qspy -c /dev/ttyACM0 -b 115200
pixi run bench-smoke
pixi run bench-full --json-out bench_results.jsonl
Useful benchmark-oriented Pixi tasks:
pixi run bench
pixi run bench-full
pixi run bench-smoke
pixi run bench-windows-like
pixi run bench-full-windows-like
pixi run bench-full-no-nodelay
pixi run bench-full-no-latency-tuning
pixi run bench-frame-rate-compare
pixi run bench-frame-rate-matrix --ethernet 192.168.10.194
pixi run perf-summary --jsonl bench_results.jsonl
pixi run perf-summary-frame-rate
Pixi forwards extra arguments after the task name to the underlying command.
That works well for bench subcommand options already baked into the task, so
pixi run bench-full --json-out bench_results.jsonl --label "lab-a" appends
one JSON result object for that run as expected.
For tasks that wrap arena-interface bench, transport selection is easier via
ARENA_ETH_IP or ARENA_SERIAL_PORT because those are top-level CLI options.
For example:
export ARENA_ETH_IP=192.168.10.194
pixi run bench-full --label linux-default --json-out bench_results.jsonl
Script-backed tasks such as bench-socket-matrix and bench-frame-rate-matrix
parse their own command-line options, so passing --ethernet or --serial
after the task name is fine there.
Task notes:
bench-fullruns the full suite plus a streaming phase usingpatterns/pat0004.pat.bench-full-windows-likedisablesTCP_QUICKACKwhile leavingTCP_NODELAYon. This is a useful approximation when comparing a Linux host with a Windows-like Ethernet socket policy.bench-full-no-nodelayisolates the effect of disablingTCP_NODELAYwhile leavingTCP_QUICKACKenabled.bench-full-no-latency-tuningdisables bothTCP_NODELAYandTCP_QUICKACK.bench-frame-rate-compareruns four stream-enabled variants back-to-back and appends labeled results tobench_artifacts/frame_rate_results.jsonl.bench-frame-rate-matrixruns the same comparison through the dedicated matrix helper and prints a delta summary relative to the default socket policy.perf-summary-frame-raterenders a compact host-side comparison from the collected frame-rate JSONL file and writesbench_artifacts/frame_rate_summary.json.
Plain pip
python -m pip install -e ".[dev]"
python -m pytest -q
python -m build
python -m twine check dist/*
Version updates
Use the Pixi helper to update the repository version consistently before a release:
pixi run version-show
pixi run version-bump 7.0.1
pixi install
version-bump updates the package metadata files and turns the current
## Unreleased changelog section into a dated release entry. Run pixi install
immediately afterward so pixi.lock is regenerated from the updated metadata
before you commit or tag the release.
Performance characterization workflow
bench_results.jsonl stores the host-side benchmark results, while QSPY
captures the raw firmware QS stream so you can compare those host-side
measurements with device-side PERF_* records such as PERF_UPD kind=SPF and
PERF_NET.
A few key metrics are usually enough to compare runs:
- command RTT mean and p99 (
command_rtt) - SPF achieved rate and p99 update RTT (
spf_updates) - stream frame rate and transmit throughput (
stream_frames) - reconnect count plus cleanup status
Quick frame-rate comparison of host socket tuning
For a repeatable “how much are the Linux socket optimizations helping?” pass, set the transport once and run the dedicated comparison task:
export ARENA_ETH_IP=192.168.10.194
pixi run bench-frame-rate-compare
pixi run perf-summary-frame-rate
This captures four labeled runs in bench_artifacts/frame_rate_results.jsonl:
linux-defaultwindows-likeno-nodelayno-latency-tuning
The summary reports the deltas relative to linux-default, including stream
rate, stream throughput, SPF achieved rate, and command RTT. Parent directories
for --json-out are created automatically, so bench_artifacts/ does not need
to exist ahead of time.
If you prefer a one-command matrix that also prints a relative delta summary to stdout, use the script-backed task instead:
pixi run bench-frame-rate-matrix --ethernet 192.168.10.194
pixi run perf-summary-frame-rate-matrix
Terminal A: start QSPY and capture the raw QS log
mkdir -p bench_artifacts/2026-03-13-eth
pixi run qtools-install
pixi run qspy -c /dev/ttyACM0 -b 115200 2>&1 | tee bench_artifacts/2026-03-13-eth/qspy.log
PowerShell:
New-Item -ItemType Directory -Force bench_artifacts\2026-03-13-eth | Out-Null
pixi run qtools-install
pixi run qspy -c COM3 -b 115200 2>&1 | Tee-Object -FilePath bench_artifacts\2026-03-13-eth\qspy.log
Leave QSPY running while the benchmark executes in a second terminal. Stop it after the benchmark completes so the log contains the full run.
Terminal B: run the host benchmark and append JSONL results
Set the transport once, then run whichever socket-policy variants you want to compare:
export ARENA_ETH_IP=192.168.10.194
pixi run bench-full --label linux-default --json-out bench_artifacts/2026-03-13-eth/bench_results.jsonl
pixi run bench-full-windows-like --label windows-like --json-out bench_artifacts/2026-03-13-eth/bench_results.jsonl
pixi run bench-full-no-nodelay --label no-nodelay --json-out bench_artifacts/2026-03-13-eth/bench_results.jsonl
pixi run bench-full-no-latency-tuning --label no-latency-tuning --json-out bench_artifacts/2026-03-13-eth/bench_results.jsonl
PowerShell:
$env:ARENA_ETH_IP = "192.168.10.194"
pixi run bench-full --label "linux-default" --json-out bench_artifacts\2026-03-13-eth\bench_results.jsonl
pixi run bench-full-windows-like --label "windows-like" --json-out bench_artifacts\2026-03-13-eth\bench_results.jsonl
For a one-command socket comparison matrix with custom output paths, use:
pixi run bench-socket-matrix --ethernet 192.168.10.194 \
--stream-path patterns/pat0004.pat \
--json-out bench_artifacts/2026-03-13-eth/bench_results.jsonl
Generate a compact performance summary
After the run, keep at least:
bench_results.jsonlfor host-side timings and metadataqspy.logfor the raw QS stream- a filtered
qspy_perf.logfor quick comparison (optional)
On POSIX you can extract just the performance lines with:
grep 'PERF_' bench_artifacts/2026-03-13-eth/qspy.log > bench_artifacts/2026-03-13-eth/qspy_perf.log
PowerShell:
Select-String -Path bench_artifacts\2026-03-13-eth\qspy.log -Pattern 'PERF_' | ForEach-Object { $_.Line } | Set-Content bench_artifacts\2026-03-13-eth\qspy_perf.log
Generate a compact text summary and optionally save a machine-readable JSON summary:
pixi run perf-summary --jsonl bench_artifacts/2026-03-13-eth/bench_results.jsonl \
--qspy-log bench_artifacts/2026-03-13-eth/qspy.log \
--baseline linux-default \
--json-out bench_artifacts/2026-03-13-eth/perf_summary.json
The summary tool groups host-side runs by label and reports the latest QSPY
PERF_* records so you can answer questions like: how much slower is the
Windows-like socket policy than the Linux default, did SPF hold 200 Hz, and did
streaming throughput change.
Interpreting cleanup warnings
Post-run ALL_OFF cleanup is intentionally treated as a warning when the
measurement phase has already completed. If the host reports
status=ok_cleanup_failed, the measured host-side statistics are still valid
and are preserved in the JSONL output. In that case:
- keep the QSPY log running and save it
- review the saved cleanup diagnostics (
ip route get ...andip neigh show ...on Linux) - compare whether QSPY shows a fresh boot/link sequence or just a host/network path hiccup
For reproducible comparisons, keep the artifact directory together with the firmware commit or tag, host computer, transport, switch/LAN notes, and the benchmark label you used.
Releasing
The repository includes GitHub Actions workflows for CI and PyPI Trusted Publishing.
Recommended release flow:
- Add release notes under
## UnreleasedinCHANGELOG.md. - Run
pixi run version-bump <version>and thenpixi install. - Run
pixi run release-checkor the equivalent pip commands above. - Commit the release changes and create a release tag such as
<version>orv<version>. - Push the tag to GitHub.
- The
publish.ymlworkflow builds the wheel and sdist, then publishes them to PyPI using Trusted Publishing.
For conda-forge guidance, see RELEASING.md.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file arena_interface-7.0.1.tar.gz.
File metadata
- Download URL: arena_interface-7.0.1.tar.gz
- Upload date:
- Size: 59.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
33551473d2b5cc6e4bbbe48229d1d459a5fcd565eec2029c3fa1192a0815050a
|
|
| MD5 |
3269205324deba022269a155d5fc2c84
|
|
| BLAKE2b-256 |
4b3ed16809fdd2b8e689b2fdeb7ac5e677db83bc696afe9a8019003f4a655f55
|
Provenance
The following attestation bundles were made for arena_interface-7.0.1.tar.gz:
Publisher:
publish.yml on janelia-python/arena_interface_python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
arena_interface-7.0.1.tar.gz -
Subject digest:
33551473d2b5cc6e4bbbe48229d1d459a5fcd565eec2029c3fa1192a0815050a - Sigstore transparency entry: 1115942614
- Sigstore integration time:
-
Permalink:
janelia-python/arena_interface_python@53a00180016b042fdee1dc371eaa424ff0017964 -
Branch / Tag:
refs/tags/7.0.1 - Owner: https://github.com/janelia-python
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@53a00180016b042fdee1dc371eaa424ff0017964 -
Trigger Event:
push
-
Statement type:
File details
Details for the file arena_interface-7.0.1-py3-none-any.whl.
File metadata
- Download URL: arena_interface-7.0.1-py3-none-any.whl
- Upload date:
- Size: 34.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6c42e7c9f9b0cdfefe833261af8ff7a1910b59b98d4b4bd95d7a01d247d82b26
|
|
| MD5 |
7a27609912d40e65cbad023620297b90
|
|
| BLAKE2b-256 |
e039eb2ba7c6fa0a78402aa5b74106a6bedeb25ab941c217d3891bd42aeb7389
|
Provenance
The following attestation bundles were made for arena_interface-7.0.1-py3-none-any.whl:
Publisher:
publish.yml on janelia-python/arena_interface_python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
arena_interface-7.0.1-py3-none-any.whl -
Subject digest:
6c42e7c9f9b0cdfefe833261af8ff7a1910b59b98d4b4bd95d7a01d247d82b26 - Sigstore transparency entry: 1115942937
- Sigstore integration time:
-
Permalink:
janelia-python/arena_interface_python@53a00180016b042fdee1dc371eaa424ff0017964 -
Branch / Tag:
refs/tags/7.0.1 - Owner: https://github.com/janelia-python
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@53a00180016b042fdee1dc371eaa424ff0017964 -
Trigger Event:
push
-
Statement type: