/ proof-of-concept / beadnet
Sign in
proof-of-concept / beadnet
beadnet / README.md
65 lines · 4.5 KBCodeBlameHistory
3A Python package for idealized percussion: networks of beads (point masses) joined by springs, bending elements and hinges, struck and integrated accurately in time, with browser components for listening to and looking at the results. It is a companion to the [bead-percussion](https://vault1.magland.org/proof-of-concept/bead-percussion) browser app, whose solver it ports, and it is meant to be driven by an AI agent that assembles models, runs them and writes HTML pages from a small set of components.
5The model, the integrator and the damping law are those of the app; see its README for the physics. Here we describe what differs: the models are built in Python, the runs record every bead, and the results are stored on disk for viewing afterwards.
7## Install
9```bash
10pip install -e . # numpy, numba, scipy; Python 3.9 or later
11pip install -e '.[test]' # adds pytest
12```
14## Use
16```python
17import beadnet as bn
18from beadnet import examples
20m = examples.drum(force=0.8) # or build a bn.Model from the helpers
21bn.save_model(m, "work/models/drum") # the model alone, for a preview
22r = bn.run(m, "work/runs/drum") # integrate and record
23print(r.summary())
24x = r.signal(412) # acceleration of bead 412, chosen after the run
25```
27```bash
28beadnet serve work # http://127.0.0.1:8790/ lists pages, runs and models
29beadnet guide # the agent guide
30```
32A page is plain HTML with custom elements:
34```html
35<script type="module" src="beadnet/beadnet.js"></script>
36<bn-run src="../runs/drum">
37 <bn-controls></bn-controls>
38 <bn-animation></bn-animation>
39 <bn-waveform></bn-waveform>
40 <bn-spectrogram scale="log"></bn-spectrogram>
41</bn-run>
42```
44[beadnet/AGENT_GUIDE.md](beadnet/AGENT_GUIDE.md) is the reference for models, runs, outputs and components; an agent should read it before building a model. `skills/beadnet/SKILL.md` wraps it as a Claude Code skill.
46## What a run records
48Unlike the app, which records one listener chosen before the run, a run here records, for every bead, the acceleration and the displacement along a chosen direction at the audio rate (48 kHz by default), with their sums over all beads, plus 3D displacement frames of all beads at a lower rate (2 kHz by default), the energy, and optionally the energy in each linear mode. The listener is therefore chosen afterwards, in Python or by clicking a bead in the browser. The acceleration at each sample is computed from the forces, with the damping step that is still pending at the sample boundary taken into account, as in the app.
50The trade-off is size. Each recorded quantity takes about 4 bytes per bead per sample, since float32 audio signals barely compress: the 2 s drum (823 beads) stores about 300 MB per quantity. Recording every bead also costs 20 to 35% more time than recording one.
52Results go into a directory that is a Zarr v2 store with gzip chunks, one bead by 32768 samples per signal chunk. The browser fetches only the chunks it needs (one bead's signal, a range of frames), and zarr-python reads the store directly; the package itself reads and writes it without a zarr dependency.
54## Accuracy and speed
56The per-bead signals agree with the app's TypeScript solver to float32 rounding for the same model and time step (`tests/test_solver.py`, with reference runs exported from the app: a nonlinear string with two strikes under Yoshida integration, a hinged dome, a plate with bending triplets and soft anchors, and friction-only damping). The tests also check the analytic modes and fundamental of a beaded string, energy conservation without damping, the hinge gradient against finite differences, and the exactness of the decay law at small amplitude for flat and curved nets.
58The kernels are compiled with numba and run on one core. On a laptop, the drum runs at about 10 times real time, the plate (1015 beads, bending triplets) about 25 times and the dome (367 beads, hinges) about 14 times, comparable to the app in the browser. Separate runs can go in parallel. A GPU path, as in the app, is not implemented.
60## Limitations
62- The viewer's 3D view is a plain canvas; it is comfortable up to a few thousand beads.
63- Bending triplets need straight or flat rest shapes; hinges handle curved ones.
64- The perturbed-twin chaos test and the small-strike comparison of the app are not built in; both are a second run of a modified model (`model.scaled_hits`, `bn.rel_diff`).
65- Mode energies are recorded when `modes=True`, but there is no component for them yet.
↑↓ move↵openescclose