feat(999.2): Tag Analysis Toolkit — 6 kind-aware analysis methods (getStats/resample/derivative/movingStat/exceedance/crossings)#376
Conversation
…Tag Analysis Toolkit, 999.3 EventViewer export) Captures the 8 GitHub issues approved during the 2026-07-08 inbox triage: - 999.2 Tag Analysis Toolkit: #223 getStats (keystone), #308 resampleUniform, #326 derivative, #312 movingStat, #316 exceedance, #328 crossings, #327 cumulativeIntegral - 999.3 EventViewer image export parity: #321 exportImage Also records the triage report at .planning/INBOX-TRIAGE.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Keystone-first: 999.2-01 getStats (Wave 1); the six analysis methods (resampleUniform, derivative, movingStat, exceedance, crossings, cumulativeIntegral) as Wave 2 depending on 01. All additive, toolbox-free, Octave-safe methods on libs/SensorThreshold/Tag.m + per-method headless tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Public getStats(tStart,tEnd) on the Tag base class returning N/Min/Max/Mean/Rms/Std/First/Last/TimeStart/TimeEnd. Toolbox-free, Octave-safe (NaN masking, not 'omitnan'), numeric-only reductions with cellstr-StateTag + empty-window guards. Delegates to getXYRange so all subclasses inherit it. Verified: 23/23 headless assertions, lint clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…328 #327) All six append to the shared libs/SensorThreshold/Tag.m base class, so they ship as one atomic wave (each depends only on the getXY/getXYRange seam, none on each other): - resampleUniform(dt,...) #308 — kind-aware uniform-grid resample - derivative(...) #326 — central/forward/backward rate of change - movingStat(window,type)#312 — rolling mean/std/max/min/rms/median - exceedance(level,...) #316 — time-above/below-threshold analysis - crossings(level,...) #328 — level-crossing times + direction - cumulativeIntegral(...)#327 — running trapezoidal totalizer Plus private option-parse/series/peak helpers. Toolbox-free and Octave-safe (hand-rolled movers + trapezoid, no 'omitnan'/movmean/cumtrapz; interp1 linear/previous only). Additive only — no property/serialization change. Verified via matlab MCP: 69 headless assertions across 6 test files pass, static analysis clean, TestDerivedTag 35/35 (no regression). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Ports DashboardEngine.exportImage's cross-platform backend (exportapp / exportgraphics->print->getframe / Octave print+stub-axes) to the EventViewer timeline figure. Format inferred from extension; notRendered + unknownImageFormat guards. Additive only. Verified via matlab MCP: 6/6 headless assertions, lint clean, TestEventViewer 7/7 (no regression). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…lemented) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…triage-df4390 # Conflicts: # .planning/STATE.md # libs/SensorThreshold/Tag.m
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
…er test
MISS_HIT requires a space after each ';' in the cell literal
{'N'; 'Min'; ...}. No behavior change; test still 23/23.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Wiki docs check for this merge: The 6 new The rest of the diff ( Generated by Claude Code |
Summary
Adds the Tag Analysis Toolkit (Phase 999.2) — 6 new toolbox-free, Octave-safe, additive methods on the
Tagbase class (libs/SensorThreshold/Tag.m), inherited by every subclass via thegetXY/getXYRangeseam. All additive: no property, serialization, or interface changes.Features (net-new)
Tag.getStats(tStart,tEnd)— N/Min/Max/Mean/Rms/Std/First/Last/TimeStart/TimeEnd (keystone)Tag.resampleUniform(dt, ...)— kind-aware uniform-grid resampleTag.derivative(...)— central/forward/backward rate of changeTag.movingStat(window, type)— rolling mean/std/max/min/rms/medianTag.exceedance(level, ...)— time-above/below-threshold analysisTag.crossings(level, ...)— level-crossing times + directionAlready shipped on
main(no longer part of this diff): #327cumulativeIntegral, #321EventViewer.exportImage.Design notes
'omitnan'), a hand-rolled centered-window loop (nomovmean/movstd),interp1linear/previous only.Tag:*OnDiscretewarnings/guards instead of fabricating interpolated values, honouring the existing ZOH-only invariant.Verification (MATLAB MCP, on the merged tree)
test_tag_getstats23,test_tag_resampleuniform10,test_tag_derivative13,test_tag_movingstat14,test_tag_crossings12,test_tag_exceedance12).Tag.m(only a pre-existingisscalarstyle hint in main'scumulativeIntegral).TestTag32/32 (main's Tag: add cumulativeIntegral() — trapezoidal totalizer series (running ∫ over getXY) #327 suite),TestEventViewer7/7 (main's EventViewer: add exportImage(path) to save the timeline figure as PNG/JPEG (parity with DashboardEngine/DetachedMirror) #321),TestDerivedTag35/35.🤖 Generated with Claude Code