Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 15 additions & 20 deletions ComtradeWorkspaceWindow.Analysis.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,12 @@ private void SetAnalysisMode(AnalysisMode mode)
PhasorView.Visibility = mode == AnalysisMode.Phasor ? Visibility.Visible : Visibility.Collapsed;
HarmonicsView.Visibility = mode == AnalysisMode.Harmonics ? Visibility.Visible : Visibility.Collapsed;
ResetViewButton.Visibility = mode == AnalysisMode.Waveform ? Visibility.Visible : Visibility.Collapsed;
FullRecordButton.Visibility = mode == AnalysisMode.Waveform ? Visibility.Visible : Visibility.Collapsed;
NavigationTextBlock.Text = mode switch
{
AnalysisMode.Phasor => "Cursor A = phasor reference • native one-cycle DFT • select an analog signal family on the left",
AnalysisMode.Harmonics => "Cursor A = harmonic reference • full-cycle native DFT • click a bar for details",
_ => "Shared trigger-relative timelineclick Cursor ACtrl/right-click Cursor Bdigital ↑/↓ = transition"
AnalysisMode.Phasor => "C1 = phasor reference • native one-cycle DFT • select an analog signal family on the left",
AnalysisMode.Harmonics => "C1 = harmonic reference • full-cycle native DFT • click a bar for details",
_ => "Wheel scrolls tracksCtrl+wheel zooms timedrag plot pansdrag C1/C2 measures • right-click places C2"
};
ApplyAnalysisModeVisuals();

Expand All @@ -85,13 +86,13 @@ private void UpdateAnalysisAvailability()
HarmonicsModeButton.IsEnabled = analog;
if (!analog)
{
PhasorModeButton.ToolTip = "Select an analog signal first. Cursor A on the waveform becomes the phasor reference.";
HarmonicsModeButton.ToolTip = "Select an analog signal first. Cursor A on the waveform becomes the harmonic reference.";
PhasorModeButton.ToolTip = "Select an analog signal first. C1 on Time Signals becomes the phasor reference.";
HarmonicsModeButton.ToolTip = "Select an analog signal first. C1 on Time Signals becomes the harmonic reference.";
}
else
{
PhasorModeButton.ToolTip = "Show same-unit fundamental RMS phasors at Cursor A (or viewport center when Cursor A is unset).";
HarmonicsModeButton.ToolTip = "Show native ArdIrec harmonic spectrum at Cursor A (or viewport center when Cursor A is unset).";
PhasorModeButton.ToolTip = "Show same-unit fundamental RMS phasors at C1 (or the visible Time Signals center when C1 is unset).";
HarmonicsModeButton.ToolTip = "Show native ArdIrec harmonic spectrum at C1 (or the visible Time Signals center when C1 is unset).";
}
}

Expand Down Expand Up @@ -126,9 +127,9 @@ private async Task RefreshNativeAnalysisAsync()
var triggerMs = ResolveTriggerMilliseconds();
var relative = timeMs is { } absolute && triggerMs is { } trigger ? absolute - trigger : (double?)null;
AnalysisReferenceTextBlock.Text = timeMs is { } ms
? $"Analysis reference: {(cursorReference ? "Cursor A" : "viewport center")} • frame {referenceFrame:N0} • " +
? $"Analysis reference: {(cursorReference ? "C1" : "visible center")} • frame {referenceFrame:N0} • " +
(relative is { } rel ? ComtradeDisturbanceTimelineMath.FormatRelativeTime(rel) : $"{ms:G7} ms")
: $"Analysis reference: {(cursorReference ? "Cursor A" : "viewport center")} • frame {referenceFrame:N0}";
: $"Analysis reference: {(cursorReference ? "C1" : "visible center")} • frame {referenceFrame:N0}";

try
{
Expand All @@ -147,7 +148,7 @@ private async Task RefreshNativeAnalysisAsync()
var subtitle = BuildAnalysisSubtitle(selectedMetadata, referenceFrame, result.Count,
"fundamental RMS • same-unit channels");
PhasorView.ShowPhasors("Phasor diagram", subtitle, result);
StatusTextBlock.Text = $"Native ArdIrec phasor analysis • {(cursorReference ? "Cursor A" : "viewport center")} • frame {referenceFrame:N0} • {result.Count} vector(s)";
StatusTextBlock.Text = $"Native ArdIrec phasor analysis • {(cursorReference ? "C1" : "visible center")} • frame {referenceFrame:N0} • {result.Count} vector(s)";
return;
}

Expand Down Expand Up @@ -176,7 +177,7 @@ private async Task RefreshNativeAnalysisAsync()
var harmonicSubtitle = BuildAnalysisSubtitle(metadata, referenceFrame, spectrum.Bins.Count,
$"orders H1…H{spectrum.Bins[^1].Order}");
HarmonicsView.ShowSpectrum("Harmonic spectrum", harmonicSubtitle, display);
StatusTextBlock.Text = $"Native ArdIrec harmonics • {(cursorReference ? "Cursor A" : "viewport center")} • THD {spectrum.ThdPercent:G5}% • " +
StatusTextBlock.Text = $"Native ArdIrec harmonics • {(cursorReference ? "C1" : "visible center")} • THD {spectrum.ThdPercent:G5}% • " +
(spectrum.DominantOrder > 1
? $"dominant H{spectrum.DominantOrder} {spectrum.DominantPercent:G4}%"
: "no meaningful distortion harmonic");
Expand All @@ -201,18 +202,12 @@ private ulong ResolveAnalysisReferenceFrame()
{
if (TryResolveDisturbanceCursorFrame(out var cursorFrame))
return cursorFrame;
if (TryResolveDisturbanceViewportCenterFrame(out var centerFrame))
return centerFrame;

var total = _record.Info.FrameCount;
if (total == 0) return 0;
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);
return (total - 1) / 2;
}

private async Task<double?> TryReadReferenceTimeMillisecondsAsync(ulong referenceFrame, CancellationToken token)
Expand Down
Loading
Loading