diff --git a/OpenTap.Plugins.PNAX/Acquisition/StoreSingleTrace.cs b/OpenTap.Plugins.PNAX/Acquisition/StoreSingleTrace.cs index 215bd96..d1ca160 100644 --- a/OpenTap.Plugins.PNAX/Acquisition/StoreSingleTrace.cs +++ b/OpenTap.Plugins.PNAX/Acquisition/StoreSingleTrace.cs @@ -15,55 +15,63 @@ namespace OpenTap.Plugins.PNAX { [Display("Store Single Trace", Groups: new[] { "Network Analyzer", "Acquisition" }, Description: "Stores trace data for a single given trace")] - public class StoreSingleTraceAdvanced : TestStep + public class StoreSingleTraceAdvanced : StoreDataBase { #region Settings - [Display("PNA", Order: 0.1)] - public PNAX PNAX { get; set; } + //[Display("PNA", Order: 0.1)] + //public PNAX PNAX { get; set; } - - [Display("Channel", Description: "Choose which channel to grab data from.", "Measurements", Order: 10)] - public Input Channel { get; set; } + [Browsable(false)] + [Display("Auto Select All Channels", Group: "Measurements", Order: 10)] + override public bool AutoSelectChannels { get; set; } = true; [Display("MNum", Groups: new[] { "Trace" }, Order: 21)] public Input mnum { get; set; } [Display("Use Trace Title as Column Name", Groups: new[] { "Publish Results" }, Order: 30)] public bool UseTraceTitle { get; set; } + #endregion public StoreSingleTraceAdvanced() { - Channel = new Input(); mnum = new Input(); UseTraceTitle = false; + MetaData = new List<(string, object)>(); } public override void Run() { - Log.Info("Channel from trace: " + Channel); + MetaData = new List<(string, object)>(); + // Supported child steps will provide MetaData to be added to the publish table + RunChildSteps(); + Log.Info("MNUM from trace: " + mnum); - SingleTraceBaseStep x = (mnum.Step as SingleTraceBaseStep); + SingleTraceBaseStep inputTrace = (mnum.Step as SingleTraceBaseStep); Log.Info("trace Window: " ); - Log.Info("trace Window: " + x.Window); - Log.Info("trace Sheet: " + x.Sheet); - Log.Info("trace tnum: " + x.tnum); - Log.Info("trace mnum: " + x.mnum); - Log.Info("trace MeasName: " + x.MeasName); + Log.Info("trace Channel: " + inputTrace.Channel); + Log.Info("trace Window: " + inputTrace.Window); + Log.Info("trace Sheet: " + inputTrace.Sheet); + Log.Info("trace tnum: " + inputTrace.tnum); + Log.Info("trace mnum: " + inputTrace.mnum); + Log.Info("trace MeasName: " + inputTrace.MeasName); + + int Channel = inputTrace.Channel; + int mnumValue = inputTrace.mnum; UpgradeVerdict(Verdict.NotSet); RunChildSteps(); //If the step supports child steps. - List> results = PNAX.StoreTraceData(Channel.Value, mnum.Value); + List> results = PNAX.StoreTraceData(Channel, mnumValue); PNAX.WaitForOperationComplete(); - string MeasName = x.MeasName; + string MeasName = inputTrace.MeasName; if (UseTraceTitle) { - MeasName = PNAX.GetTraceTitle(Channel.Value, mnum.Value, MeasName); + MeasName = PNAX.GetTraceTitle(Channel, mnumValue, MeasName); } var xResult = results.Where((item, index) => index % 2 == 0).ToList(); @@ -103,7 +111,93 @@ public override void Run() } - ResultTable resultTable = new ResultTable($"Channel_{Channel}", resultColumns.ToArray()); + // Find if limit is turned on for this trace + bool limitON = PNAX.GetLimitTestOn(Channel, mnumValue); + + if (limitON) + { + string strPF = PNAX.GetPF(Channel, mnumValue); + List pf = new List(); + // Create a list of n values all equal to strPF + string verdict = strPF.Equals("0") ? Verdict.Pass.ToString() : Verdict.Fail.ToString(); + for (int pfIndex = 0; pfIndex < freqLength; pfIndex++) + { + pf.Add(verdict); + } + + var limitReportAllStr = PNAX.GetLimits(Channel, mnumValue); + var limitReportAll = limitReportAllStr.Split(',').ToList(); + var x1 = limitReportAll.Where((item, index) => ((index == 0) || ((index >= 4) && (index % 4 == 0)))).ToList(); + var x2 = limitReportAll.Where((item, index) => ((index == 1) || ((index >= 5) && (index % 4 == 1)))).ToList(); + var x3 = limitReportAll.Where((item, index) => ((index == 2) || ((index >= 6) && (index % 4 == 2)))).ToList(); + var x4 = limitReportAll.Where((item, index) => ((index == 3) || ((index >= 7) && (index % 4 == 3)))).ToList(); + + // append global pf + resultColumn = new ResultColumn($"{MeasName}_GlobalPF", pf.ToArray()); + resultColumns.Add(resultColumn); + if (resultColumn.Data.GetValue(0).Equals("Fail")) + { + Log.Warning($"Trace: {MeasName} failed limits!"); + UpgradeVerdict(Verdict.Fail); + } + + // append xaxisvalues + //resultColumn = new ResultColumn($"{MeasName}_XAxis", x1[i].Select(double.Parse).Select(x => Math.Round(x, 2)).ToArray()); + //if (false) + //{ + // resultColumns.Add(resultColumn); + //} + + // append pf + List pfByRow = new List(); + var arraypf = x2.Select(double.Parse).Select(x => Math.Round(x, 2)).ToArray(); + foreach (var item in arraypf) + { + Verdict a = item == 1 ? Verdict.Pass : Verdict.Fail; + pfByRow.Add(a.ToString()); + } + resultColumn = new ResultColumn($"{MeasName}_PF", pfByRow.ToArray()); + resultColumns.Add(resultColumn); + + // append upperlimit + resultColumn = new ResultColumn($"{MeasName}_UL", x3.Select(double.Parse).Select(x => Math.Round(x, 2)).ToArray()); + if ((double)resultColumn.Data.GetValue(0) != 3.40282346639E+38) + { + resultColumns.Add(resultColumn); + } + + // append lowerlimit + resultColumn = new ResultColumn($"{MeasName}_LL", x4.Select(double.Parse).Select(x => Math.Round(x, 2)).ToArray()); + if ((double)resultColumn.Data.GetValue(0) != -3.40282346639E+38) + { + resultColumns.Add(resultColumn); + } + } + + // if MetaData available + if ((MetaData != null) && (MetaData.Count > 0)) + { + // for every item in metadata + foreach (var i in MetaData) + { + object[] objMetaData = new object[freqLength]; + for (int data = 0; data < freqLength; data++) + { + objMetaData[data] = i.Item2; + } + ResultColumn resultColumnMeta = new ResultColumn(i.Item1, objMetaData); + + // create a new column with Rows = lastColumn.length + // column name = metadata description + // every element should have the same metadata value + // append column to resultColumns + resultColumns.Add(resultColumnMeta); + } + } + + + // Publish Table + ResultTable resultTable = new ResultTable($"{MeasName}", resultColumns.ToArray()); Results.PublishTable(resultTable); UpgradeVerdict(Verdict.Pass); diff --git a/OpenTap.Plugins.PNAX/Instrument/PNA.cs b/OpenTap.Plugins.PNAX/Instrument/PNA.cs index 1447483..0b1f458 100644 --- a/OpenTap.Plugins.PNAX/Instrument/PNA.cs +++ b/OpenTap.Plugins.PNAX/Instrument/PNA.cs @@ -577,6 +577,11 @@ public void AutoScaleWindow(int wnum) ScpiCommand($"DISPlay:WINDow{wnum}:Y:AUTO"); } + public void AutoScaleTrace(int mnum) + { + ScpiCommand($"DISPlay:MEASure{mnum}:Y:AUTO"); + } + public void DisplayWindowSize(int wnum, VNAWindowSize windowSize) { string size = Scpi.Format("{0}", windowSize); diff --git a/OpenTap.Plugins.PNAX/Instrument/PNALoadMeasStore.cs b/OpenTap.Plugins.PNAX/Instrument/PNALoadMeasStore.cs index 99cab23..1afd3b9 100644 --- a/OpenTap.Plugins.PNAX/Instrument/PNALoadMeasStore.cs +++ b/OpenTap.Plugins.PNAX/Instrument/PNALoadMeasStore.cs @@ -260,6 +260,19 @@ public List> StoreTraceData(List channelsList) return resultsList; } + public string GetPF(int Channel, int mnum) + { + // now query PF + string strPF = IsModelA ? ScpiQuery($"CALC{Channel}:LIMit:FAIL?") : ScpiQuery($"CALC{Channel}:MEAS{mnum}:LIMit:FAIL?"); + return strPF; + } + + public string GetLimits(int Channel, int mnum) + { + string limitReportAllStr = IsModelA ? "" : ScpiQuery($"CALC{Channel}:Meas{mnum}:LIMit:REPort:ALL?"); + return limitReportAllStr; + } + public List> StoreTraceData(int Channel, int mnum) { ScpiCommand(":FORM:DATA ASCii, 0"); diff --git a/OpenTap.Plugins.PNAX/Instrument/PNAMarkerSearch.cs b/OpenTap.Plugins.PNAX/Instrument/PNAMarkerSearch.cs index 2383946..41af405 100644 --- a/OpenTap.Plugins.PNAX/Instrument/PNAMarkerSearch.cs +++ b/OpenTap.Plugins.PNAX/Instrument/PNAMarkerSearch.cs @@ -71,6 +71,22 @@ public void CalculateMeasureMarkerFunctionPeak(int Channel, int mnum, int mkr) WaitForOperationComplete(); } + public void CalculateMeasureMarkerFunctionPeakThreshold(int Channel, int mnum, int mkr, double value) + { + ScpiCommand($"CALCulate{Channel}:MEASure{mnum}:MARKer{mkr}:FUNCtion:PEAK:THReshold {value}"); + } + + public void CalculateMeasureMarkerFunctionPeakExcursion(int Channel, int mnum, int mkr, double value) + { + ScpiCommand($"CALCulate{Channel}:MEASure{mnum}:MARKer{mkr}:FUNCtion:PEAK:EXCursion {value}"); + } + + public void CalculateMeasureMarkerFunctionPeakPolarity(int Channel, int mnum, int mkr, SAMultiPeakSearchPolarityEnumType value) + { + string scpi = Scpi.Format("{0}", value); + ScpiCommand($"CALCulate{Channel}:MEASure{mnum}:MARKer{mkr}:FUNCtion:PEAK:POLarity {scpi}"); + } + public void CalculateMeasureMarkerSetCenter(int Channel, int mnum, int mkr) { ScpiCommand($"CALCulate{Channel}:MEASure{mnum}:MARKer{mkr}:SET CENTer"); @@ -94,5 +110,13 @@ public bool CalculateMeasureMarkerState(int Channel, int mnum, int mkr) { return ScpiQuery($"CALCulate{Channel}:MEASure{mnum}:MARKer{mkr}:STATe?"); } + + public string GetMeasurementName(int mnum) + { + string retStr = ScpiQuery($"SYSTem:MEASure{mnum}:NAME?"); + retStr = retStr.Replace("\"", ""); + return retStr; + } + } } diff --git a/OpenTap.Plugins.PNAX/LMS/StoreDataBase.cs b/OpenTap.Plugins.PNAX/LMS/StoreDataBase.cs index 5b902f9..6a9a4f0 100644 --- a/OpenTap.Plugins.PNAX/LMS/StoreDataBase.cs +++ b/OpenTap.Plugins.PNAX/LMS/StoreDataBase.cs @@ -22,7 +22,7 @@ public class StoreDataBase: TestStep [Display("Auto Select All Channels", Group: "Measurements", Order: 10)] - public bool AutoSelectChannels { get; set; } + public virtual bool AutoSelectChannels { get; set; } [EnabledIf("AutoSelectChannels", false, HideIfDisabled = true)] [Display("Channels", Description: "Choose which channels to grab data from.", "Measurements", Order: 10.1)] diff --git a/OpenTap.Plugins.PNAX/Network Analyzer Steps/AutoScaleTrace.cs b/OpenTap.Plugins.PNAX/Network Analyzer Steps/AutoScaleTrace.cs new file mode 100644 index 0000000..36b4439 --- /dev/null +++ b/OpenTap.Plugins.PNAX/Network Analyzer Steps/AutoScaleTrace.cs @@ -0,0 +1,67 @@ +using OpenTap; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; + +namespace OpenTap.Plugins.PNAX +{ + [Display("Auto Scale Trace", Groups: new[] { "Network Analyzer" }, Description: "Auto scale window")] + public class AutoScaleTrace : TestStep + { + #region Settings + [Display("PNA", Order: 0.1)] + public PNAX PNAX { get; set; } + + [Display("Use Trace Output", Description: "Select a trace to obtain the values of: Channel, Window, TNUM and MNUM", Groups: new[] { "Measurements" }, Order: 10)] + public bool UseTraceOutput { get; set; } + + [EnabledIf("UseTraceOutput", true, HideIfDisabled = true)] + [Display("MNum", Groups: new[] { "Trace" }, Order: 20)] + public Input mnum { get; set; } + + [EnabledIf("UseTraceOutput", false, HideIfDisabled = true)] + [Display("MNum Value", Groups: new[] { "Trace" }, Order: 23)] + public int mnumValue { get; set; } + #endregion + + public AutoScaleTrace() + { + UseTraceOutput = true; + + mnum = new Input(); + mnumValue = 1; + } + + public override void Run() + { + UpgradeVerdict(Verdict.NotSet); + + if (UseTraceOutput) + { + if (mnum == null) + { + Log.Error("Make sure to select a trace"); + UpgradeVerdict(Verdict.Error); + } + + // Get the values from the input + SingleTraceBaseStep x = (mnum.Step as SingleTraceBaseStep); + + Log.Info("trace Window: "); + Log.Info("trace Window: " + x.Window); + Log.Info("trace Sheet: " + x.Sheet); + Log.Info("trace tnum: " + x.tnum); + Log.Info("trace mnum: " + x.mnum); + Log.Info("trace MeasName: " + x.MeasName); + + mnumValue = x.mnum; + } + + PNAX.AutoScaleTrace(mnumValue); + + UpgradeVerdict(Verdict.Pass); + } + } +} diff --git a/OpenTap.Plugins.PNAX/Traces/PeakSearch.cs b/OpenTap.Plugins.PNAX/Traces/PeakSearch.cs new file mode 100644 index 0000000..12e011c --- /dev/null +++ b/OpenTap.Plugins.PNAX/Traces/PeakSearch.cs @@ -0,0 +1,174 @@ +// Author: MyName +// Copyright: Copyright 2023 Keysight Technologies +// You have a royalty-free right to use, modify, reproduce and distribute +// the sample application files (and/or any modified version) in any way +// you find useful, provided that you agree that Keysight Technologies has no +// warranty, obligations or liability for any sample application files. +using OpenTap; +using OpenTap.Plugins.PNAX; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; + +namespace OpenTap.Plugins.PNAX +{ + [Display("Peak Search", Groups: new[] { "Network Analyzer", "Trace" }, Description: "Insert a description here")] + public class PeakSearch : TestStep + { + #region Settings + [Display("PNA", Order: 0.1)] + public PNAX PNAX { get; set; } + + [Display("Use Trace Output", Description: "Select a trace to obtain the values of: Channel, Window, TNUM and MNUM", Groups: new[] { "Measurements" }, Order: 10)] + public bool UseTraceOutput { get; set; } + + [EnabledIf("UseTraceOutput", true, HideIfDisabled = true)] + [Display("MNum", Groups: new[] { "Trace" }, Order: 20)] + public Input mnum { get; set; } + + [EnabledIf("UseTraceOutput", false, HideIfDisabled = true)] + [Display("Channel", Description: "Choose which channel to grab data from.", "Measurements", Order: 11)] + public int Channel { get; set; } + + [Display("Window", Groups: new[] { "Trace" }, Order: 21)] + public int Window { get; set; } + + [EnabledIf("UseTraceOutput", false, HideIfDisabled = true)] + [Display("TNum", Groups: new[] { "Trace" }, Order: 22)] + public int tnum { get; set; } + + [EnabledIf("UseTraceOutput", false, HideIfDisabled = true)] + [Display("MNum Value", Groups: new[] { "Trace" }, Order: 23)] + public int mnumValue { get; set; } + + [Display("Marker Number", Groups: new[] { "Trace" }, Order: 30)] + public int mkr { get; set; } + + [Display("Peak Threshold", Groups: new[] { "Trace" }, Order: 31)] + public double PeakThreshold { get; set; } + + [Display("Peak Excursion", Groups: new[] { "Trace" }, Order: 32)] + public double PeakExcursion { get; set; } + + [Display("Peak Polarity", Groups: new[] { "Trace" }, Order: 33)] + public SAMultiPeakSearchPolarityEnumType PeakPolarity { get; set; } + + + [Display("Publish Results", Groups: new[] { "Results" }, Order: 40)] + public bool PublishResults { get; set; } + + [EnabledIf("PublishResults", true, HideIfDisabled = true)] + [Display("Result File Name", Group: "Results", Order: 41)] + public MacroString FileName { get; set; } + + [Display("X", Groups: new[] { "Results" }, Order: 51)] + public double mrkrX { get; set; } + + [Display("Y", Groups: new[] { "Results" }, Order: 52)] + public double mrkrY { get; set; } + #endregion + + public PeakSearch() + { + UseTraceOutput = true; + + mnum = new Input(); + + Channel = 1; + Window = 1; + mnumValue = 1; + tnum = 1; + mkr = 1; + + PeakThreshold = -100; + PeakExcursion = 3; + PeakPolarity = SAMultiPeakSearchPolarityEnumType.POS; + + PublishResults = true; + FileName = new MacroString(this) { Text = "PeakSearch_Markers" }; + } + + public override void Run() + { + mrkrY = double.NaN; + string MeasName = ""; + + if (UseTraceOutput) + { + if (mnum == null) + { + Log.Error("Make sure to select a trace"); + UpgradeVerdict(Verdict.Error); + } + + // Get the values from the input + SingleTraceBaseStep x = (mnum.Step as SingleTraceBaseStep); + + Log.Info("trace Window: "); + Log.Info("trace Channel: " + x.Channel); + Log.Info("trace Window: " + x.Window); + Log.Info("trace Sheet: " + x.Sheet); + Log.Info("trace tnum: " + x.tnum); + Log.Info("trace mnum: " + x.mnum); + Log.Info("trace MeasName: " + x.MeasName); + + Channel = x.Channel; + Window = x.Window; + mnumValue = x.mnum; + tnum = x.tnum; + MeasName = x.MeasName; + } + else + { + MeasName = PNAX.GetMeasurementName(mnumValue); + } + + // Set Marker state + PNAX.SetMarkerState(Channel, mnumValue, mkr, SAOnOffTypeEnum.On); + + // Set search settings + PNAX.CalculateMeasureMarkerFunctionPeakThreshold(Channel, mnumValue, mkr, PeakThreshold); + PNAX.CalculateMeasureMarkerFunctionPeakExcursion(Channel, mnumValue, mkr, PeakExcursion); + PNAX.CalculateMeasureMarkerFunctionPeakPolarity(Channel, mnumValue, mkr, PeakPolarity); + + // Execute Peak Search + PNAX.CalculateMeasureMarkerFunctionPeak(Channel, mnumValue, mkr); + + // Get the marker value + MeasName = PNAX.GetTraceTitle(Channel, mnumValue, MeasName); + mrkrX = PNAX.ScpiQuery($"CALCulate{Channel}:MEASure{mnumValue}:MARKer{mkr}:X?"); + var yString = PNAX.ScpiQuery($"CALCulate{Channel}:MEASure{mnumValue}:MARKer{mkr}:Y?"); + var y = yString.Split(',').Select(double.Parse).ToList(); + mrkrY = y[0]; + Log.Info($"Found Marker {mkr} for Trace: {MeasName}, X:{mrkrX} Y:{mrkrY}"); + + + + // publish it + if (PublishResults) + { + string publishFileName = FileName.Expand(PlanRun); + List ResultNames = new List(); + List ResultValues = new List(); + + ResultNames.Add("Test Type"); + ResultValues.Add("Marker"); + + ResultNames.Add("Frequency (Hz)"); + ResultValues.Add(mrkrX); + + ResultNames.Add(MeasName); + ResultValues.Add(mrkrY); + + Results.Publish(publishFileName, ResultNames, ResultValues.ToArray()); + } + + UpgradeVerdict(Verdict.Pass); + } + + } + + +}