docs: the noise probe arms at 4 s, not 3, and why
`UDPSCOPE_PROBE_NOISE_MS=3000` collides with `enable_all_probe`'s own last act, which fires at
`ENABLE_ALL_MS + 2000` = 3 s: that lambda walks `signal_list` for the front channel's acquire
tick and clicks it, and a probe that installs a math graph at the same instant rebuilds the
signal panel under it. The off-step then emits `active` on a freed `GtkCheckButton` --
`GLib-GObject-CRITICAL: instance with invalid (NULL) class pointer`, stack in
`enable_all_probe()::{lambda}` -- which the baseline ("no Gtk-CRITICAL at all") counts as a
finding. Confirmed by bisection: armed at 3 s it is reproducible, at 4 s it is gone, and a plain
exit-dump run shows none.
That fragility is the probe's, not the feature's, and it is now documented beside the recipe: every
documented probe time is offset from `ENABLE_ALL_MS + 2000`, not merely from the other probes.
The reading times move with it (legs ~11.5 s, de-noise ~16.5 s, both inside the same 18 s exit),
and the corrected run reproduces every documented figure bit for bit.
Readings at 4 s: `setup channels=1`, `trigger band: bare=49/2 band=7/2 ratio=7.00`,
`trigger hf: hf=7/2 band+hf=7/2 band=7`, `pw`/`period band`/`period hf` exactly 0.200000,
`measure windows=2`, `denoise raw=2.987696/1 denoised=2.000000/1 ratio=0.669 channels=1`, no
`Gtk-CRITICAL`.
This commit is contained in:
1 parent
749b34a2cb
commit
667ed0c100
2 files changed
+18
-8
No files matched your search
@@ -1312,8 +1312,10 @@ while the edit runs) and never falls to 0, which is what a rebuild would do. Eve
|
|||||||
applied *and* acquired, so the channel's first sample is the first one after stage 3, and a peak-to-peak
|
applied *and* acquired, so the channel's first sample is the first one after stage 3, and a peak-to-peak
|
||||||
needs a window holding a trough *and* a crest: twelve cycles of the 5 Hz source.
|
needs a window holding a trough *and* a crest: twelve cycles of the 5 Hz source.
|
||||||
|
|
||||||
With `UDPSCOPE_PROBE_NOISE_MS=3000` the legs therefore land at about 10.5 s and the last line at 15.5 s,
|
With `UDPSCOPE_PROBE_NOISE_MS=4000` the legs therefore land at about 11.5 s and the last line at 16.5 s,
|
||||||
which is why the documented run needs `UDPSCOPE_EXIT_AFTER_MS=18000`.
|
which is why the documented run needs `UDPSCOPE_EXIT_AFTER_MS=18000`. Four seconds and not three: the
|
||||||
|
enable-all probe's own last act, a click on the front channel's tick at `ENABLE_ALL_MS + 2000`, rebuilds
|
||||||
|
nothing itself but *is* rebuilt under when a graph is installed at its instant -- see `verification.md`.
|
||||||
|
|
||||||
- **`setup channels=1`** -- one math channel was installed, and it is printed by the *first* stage, before
|
- **`setup channels=1`** -- one math channel was installed, and it is printed by the *first* stage, before
|
||||||
any leg: it is the line that says the graph exists at all. A count above 1 means a session file from an
|
any leg: it is the line that says the graph exists at all. A count above 1 means a session file from an
|
||||||
|
|||||||
@@ -536,20 +536,28 @@ python3 tools/mock_udpstreamer.py --port 8108 --rate 1300000 --batch 1000 --dura
|
|||||||
--spike-every 0.005 --spike-amp 0.5 --spike-width 2 > /tmp/noise-mock.log 2>&1 &
|
--spike-every 0.005 --spike-amp 0.5 --spike-width 2 > /tmp/noise-mock.log 2>&1 &
|
||||||
sleep 1.5
|
sleep 1.5
|
||||||
xvfb-run -a env UDPSCOPE_EXIT_AFTER_MS=18000 UDPSCOPE_ENABLE_ALL_MS=1000 \
|
xvfb-run -a env UDPSCOPE_EXIT_AFTER_MS=18000 UDPSCOPE_ENABLE_ALL_MS=1000 \
|
||||||
UDPSCOPE_PROBE_NOISE_MS=3000 \
|
UDPSCOPE_PROBE_NOISE_MS=4000 \
|
||||||
./build/udpscope --server 127.0.0.1 --port 8108 2>&1 | grep -E 'noise-probe|CRITICAL'
|
./build/udpscope --server 127.0.0.1 --port 8108 2>&1 | grep -E 'noise-probe|CRITICAL'
|
||||||
```
|
```
|
||||||
|
|
||||||
`UDPSCOPE_PROBE_NOISE_MS` is **not the time its readings are taken**. It times the probe's first stage, which
|
`UDPSCOPE_PROBE_NOISE_MS` is **not the time its readings are taken**. It times the probe's first stage, which
|
||||||
installs a math graph through `apply_math_channels()` -- and that is a *structural rebuild* that replaces the
|
installs a math graph through `apply_math_channels()` -- and that is a *structural rebuild* that replaces the
|
||||||
buffer and drops its history. Every reading the probe takes is over retained history, so the rebuild has to
|
buffer and drops its history. Every reading the probe takes is over retained history, so the rebuild has to
|
||||||
happen seconds *before* them, and the chain is what the number is really choosing: `3000` puts the graph in at
|
happen seconds *before* them, and the chain is what the number is really choosing: `4000` puts the graph in at
|
||||||
3 s, `noise_probe` at 8 s (it enables the signals it measures itself and waits 2.5 s for the ring to refill
|
4 s, `noise_probe` at 9 s (it enables the signals it measures itself and waits 2.5 s for the ring to refill
|
||||||
after *that* change), the legs and the five measurements at about 10.5 s, the de-noise channel enabled at
|
after *that* change), the legs and the five measurements at about 11.5 s, the de-noise channel enabled at
|
||||||
13 s, and the de-noise reading at 15.5 s -- hence the 18 s exit and the 20 s mock. **Collapsing the two
|
14 s, and the de-noise reading at 16.5 s -- hence the 18 s exit and the 20 s mock. **Collapsing the two
|
||||||
stages into one is the failure mode**: a probe that rebuilt the buffer at 10.5 s and then scanned it
|
stages into one is the failure mode**: a probe that rebuilt the buffer at 11.5 s and then scanned it
|
||||||
immediately would read `bare=0` on every search leg, which looks exactly like a broken comparator.
|
immediately would read `bare=0` on every search leg, which looks exactly like a broken comparator.
|
||||||
|
|
||||||
|
**Why 4 s and not 3.** `enable_all_probe`'s last act is a timeout of its own, `ENABLE_ALL_MS + 2000` -- 3 s
|
||||||
|
under this recipe -- which walks `signal_list` for the front channel's acquire tick and clicks it. A probe
|
||||||
|
that installs a math graph at that same instant rebuilds the signal panel under it, and the off-step then
|
||||||
|
emits `active` on a freed `GtkCheckButton`: `GLib-GObject-CRITICAL: instance with invalid (NULL) class
|
||||||
|
pointer`, with the backtrace in `enable_all_probe()::{lambda}`. It is a real fragility of that probe's lookup
|
||||||
|
and not of the feature, and it is why every documented probe time is offset from `ENABLE_ALL_MS + 2000`, not
|
||||||
|
merely from each other.
|
||||||
|
|
||||||
The de-noise channel is installed *disabled* and enabled only for its own reading (stage 3). An acquired
|
The de-noise channel is installed *disabled* and enabled only for its own reading (stage 3). An acquired
|
||||||
channel is a share of the ring, so a fifth one shortens every channel's retained span -- and the six leg
|
channel is a share of the ring, so a fifth one shortens every channel's retained span -- and the six leg
|
||||||
counts and `pkpk bare` all scale with that span. The readings above the de-noise line belong to the older
|
counts and `pkpk bare` all scale with that span. The readings above the de-noise line belong to the older
|
||||||
|
|||||||
Reference in new issue
Block a user