fix: math in a file view -- the buffer was emptied, and the derived ring filled twice
Two defects, both reached by adding a math channel to an open waveform or a replayed
event, and both measured before and after.
**A file view has no producer, so a structural change left it empty.** `set_math_channels()`
rebuilds the channels *and* the buffer, and a rebuild drops the history: right for a stream,
whose producer refills it from the next packet, and wrong for a file, which has nothing to
refill it with. The `--open` dump read `0 samples vs 0 time slots` for *every* channel,
the file's own `sine`/`square`/`ramp`/`noise` included, though the load had reported 402 --
that is what "adding a math node breaks the plotter" was. `reload_file_view()` re-reads the
file after such a change, which is also what computes the derived channels over it: the
load's own pushes run the math once the set is in place, so `--open` with a session that
defines graphs works for the first time.
**The file path pushed into the derived rings, and so did the engine.** `push_loaded_slot()`
did not honour the rule `ChannelInfo::math` states for the packet path ("the ingest must skip
it"), so each loaded slot put a value in a derived ring and `push_math_sample()` then put the
computed one: two samples per slot, a trace at double rate -- the derived channels read
`804 samples vs 402 time slots`. Skipping them there is the whole fix.
Readings now, all equal, which is the assertion this file's own invariant makes:
--open the file: math x2 402 samples vs 402 time slots, y=[-1.9021, 0.0063] (2x the sine)
math lp 402 vs 402, mean=-0.4900 (a real filter output, not zero)
live: math x2 25100 vs 25100
replayed event: math x2 4000 vs 4000
I first tried filtering the file's *derived columns* out by name, since an export writes
every plotted channel. It removed the double count and zeroed `math lp`, because the column
it dropped was the source a session graph reads -- so it is reverted: those columns are
legitimate data, and the fix belongs in the push, not the loader.
This commit is contained in:
1 parent
c3d588f03d
commit
b090cc2a21
5 files changed
+52
No files matched your search
@@ -36,6 +36,23 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
||||
`visible_samples()` reading row 0's axis after the window was destroyed, and
|
||||
`UDPSCOPE_EXIT_AFTER_MS` arms the trigger first, so the dump can land in `Waiting`. The live
|
||||
`ch N '<name>' ... y=[..]` lines are the race-free reading of the same thing.
|
||||
- **A file view has no producer, so a structural change would leave it empty.** `set_math_channels()`
|
||||
rebuilds the channels *and* the buffer, and a rebuild drops the history: right for a stream, whose producer
|
||||
refills it from the next packet, and wrong for a file, which has nothing to refill it with. Adding a math
|
||||
channel to an open waveform therefore emptied *every* channel -- `samples=0` on the sources too, which a user
|
||||
reads as "the plot is broken" -- and the same emptiness follows any structural change in a file view.
|
||||
`reload_file_view()` (in `ui.cpp`) re-reads the file after such a change, which is also what computes the
|
||||
derived channels over it: the load's own pushes run the math once the set is in place. It is why `--open`
|
||||
works at all with a session that defines math channels, since `main()` loads the file *before* the UI (and
|
||||
so before the session's graphs) exists.
|
||||
- **Every path that fills a store must skip a derived channel, not just the packet path.**
|
||||
`ChannelInfo::math` states the rule for the ingest; `push_loaded_slot()` broke it, so loading a file pushed
|
||||
its own value into each derived ring and `push_math_sample()` then pushed the computed one: two samples per
|
||||
slot, i.e. a trace at double rate. The reading that catches it is the one already in this file --
|
||||
`math '<name>': N samples vs M time slots` must be **equal** -- and a file view now has to be read as well
|
||||
as a live one (`--open <the file>` with `UDPSCOPE_PROBE_MATH_MS`). An export writes every *plotted* channel,
|
||||
so a file carries the derived ones as ordinary columns: those are real channels and are filled normally,
|
||||
which is why the fix is in the push and not in the loader.
|
||||
`math cost: S slots, N ns/slot (T timed), X ms total est` is the per-slot cost; see the
|
||||
math-cost invariant below for why it is sampled, why it is an upper bound, and why a figure
|
||||
anywhere in 78--101 ns/slot is one reading of the same thing.
|
||||
|
||||
Reference in new issue
Block a user