Skip to content

P1C: add native COMTRADE phasor and harmonics workspace views - #294

Merged
masarray merged 9 commits into
mainfrom
feat/p1c-comtrade-analysis-views
Sep 9, 2026
Merged

masarray merged 9 commits into
mainfrom
feat/p1c-comtrade-analysis-views

Conversation

@masarray

@masarray masarray commented Sep 9, 2026

Copy link
Copy Markdown
Owner

P1C — ARSAS-native COMTRADE analysis views

Build on merged P1B.3 and keep ARSAS as the product shell while reusing ArdIrec's native analysis engine.

Engine

  • Pin merged ArdIrec P1C cfcd65adf853b6707ee54a89dd30328db8827f0b.
  • Managed bridge consumes additive ABI-1 exports for fundamental RMS phasor and harmonic spectrum.
  • No phasor/harmonic DSP formula is duplicated in C#; native results come from ArdIrec core.
  • Managed integration tests validate x64 C struct layouts and invoke the analysis exports through the packaged DLL path.

WPF workspace

  • Add top-level Waveform | Phasor | Harmonics analysis modes.
  • Keep digital signals in Waveform mode; Phasor/Harmonics are enabled only for analog channels.
  • Add engineering polar phasor control with phase colors, RMS magnitude/angle legend, normalized vector scale and same-unit grouping.
  • Add harmonic bar spectrum with Fundamental, THD, dominant harmonic, sample rate, Nyquist order and per-harmonic magnitude/%/angle details.
  • Analysis runs off the UI thread under the existing native record lifetime gate.
  • Current P1C reference is the center frame of the active absolute source viewport; this remains stable across P1B.3 large-record native reloads.
  • Qt Full analysis remains available as a compatibility/field-validation fallback.

Validation

Draft until Build ARSAS, COMTRADE cross-repo integration, SV regression and Windows installer are green on final head.

@masarray
masarray marked this pull request as ready for review September 9, 2026 15:08
@masarray
masarray merged commit 46614a1 into main Sep 9, 2026
4 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5434fe7fa0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +198 to +206
var viewport = _requestedSourceViewport.FrameCount > 0
? _requestedSourceViewport
: _loadedSourceViewport.FrameCount > 0
? _loadedSourceViewport
: ComtradeAbsoluteViewportMath.Full(total);
viewport = ComtradeAbsoluteViewportMath.Normalize(viewport, total);
if (viewport.FrameCount == 0) return Math.Min(total - 1, viewport.StartFrame);
var offset = (viewport.FrameCount - 1) / 2;
return Math.Min(total - 1, viewport.StartFrame + offset);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use the visible waveform window as the analysis reference

For records with 500,000 frames or fewer, waveform zooming and panning occur only inside ComtradeWaveformView, while _requestedSourceViewport and _loadedSourceViewport remain the full record. Consequently, after a user zooms to a fault and opens Phasor or Harmonics, this method still analyzes the full-record midpoint rather than the visible window's midpoint, producing results for the wrong time despite presenting them as the current analysis reference.

Useful? React with 👍 / 👎.

Comment on lines +248 to +252
var vectors = new List<ComtradePhasorVector>();
foreach (var item in candidates.Take(8))
{
token.ThrowIfCancellationRequested();
var phasor = _record.ReadPhasor(checked((uint)item.index), referenceFrame);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep the selected channel in truncated phasor groups

When more than eight channels share the selected channel's units or circuit, Take(8) chooses the first channels in record order and can exclude the channel the user actually selected. Selecting a later channel then renders unrelated vectors while the subtitle and reference metadata still name the selected channel, so the displayed analysis is misleading; reserve a slot for the selected channel before applying the group limit.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant