chr
2026-04-05 fe750b791d5b517cc4e9bc8e99a9a75139a0cfba
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
//Copyright 2012-2019 Keysight Technologies
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
//http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Xml.Serialization;
using OpenTap;
 
 
/// <summary>
/// This example contains a TAP plugin with simulated instrument and DUT. It shows 
/// the basic interaction between Test Steps, DUTs, and Instruments. More detail 
/// on the features found in the example can be found in the PluginDevelopment directory.
 
/// The project includes a SIMULATED: 
/// -   GeneratorInstrument (TAP Instrument).
/// -   LowPassFilterDut (TAP DUT).
 
/// MeasurePeakAmplitudeTestStep (this file) is a TAP Test Step that:
/// 1.    Programs the generator.
/// 2.    Configures the low pass filter.
/// 3.    Collects the results from the low pass filter.  
/// 4.  Publishes results to any configured result listeners. 
/// </summary>
 
namespace OpenTap.Plugins.ExamplePlugin
{
    // The display attribute defines the grouping, name and description of settings in the Add New Step window.    
    [Display(Groups: new[] { "Examples",  "Example Plugin" }, Name: "Measure Peak Amplitude",  
        Description: "Checks the maximum value of a waveform after passing through a low pass filter.")]
    // All Test Steps inherit from the TestStep base class.
    public class MeasurePeakAmplitudeTestStep : TestStep
    {
        #region Settings
 
        // Public properties with a getter and a setter will be shown in the TAP GUI.
        // Non public properties are not shown in the GUI.
        public double[] InputData { get; set; }
 
        // The display attribute can be used to define how Step Settings (Properties) appear 
        // in the Step Settings panel.
        [Display(Group: "Generator Settings", Name: "Generator", Order: 1.1)]
        // Instruments are associated with a Test Step by adding a property of the desired instrument type.
        // This can be an exact type, an interface, or base type such as ScpiInstrument, or Instrument.
        public GeneratorInstrument MyGenerator { get; set; }
 
        // DUT associations are added the same way as Instruments.
        [Display(Group: "Filter (DUT) Settings", Name: "Filter", Order: 2.1)]
        public LowPassFilterDut MyFilter { get; set; }
 
        // Order is used to sort items within a group
        [Display(Group: "Filter (DUT) Settings", Name: "Window Size", Order: 2.2,
            Description: "Defines the size of the moving average window.")]
        public int WindowSize { get; set; }
 
        // Public properties are serialized upon loading/saving the TestPlan.
        // The XmlIgnore attribute indicates that the data should not be serialized.
        // This can be used when the user is required to specify a value, and there is no default value.
        [XmlIgnore]
        // Properties with private setters are not shown in the GUI. However, you may wish 
        // to have a "read only" view of a property. To achieve that, use the Browsable(true) 
        // attribute, and keep the setter private, as shown below.
        [Browsable(true)]  
        [Display(Group: "Scope Settings", Name: "Output Data", Order: 3.1)]
        public double[] ReadOnlyOutputData { get; private set; }
 
        // Limit checking is usually done by creating Limit Settings, and then comparing the limits 
        // to the result values in the Run method (see below).
        [Display(Group: "Limit Checking", Name: "Limit Check Enabled", Order: 4.1)]
        public bool LimitCheckEnabled { get; set; }
 
        [Display(Group: "Limit Checking", Name: "Max Amplitude", Order: 4.2,
            Description: "The maximum amplitude allowed. If exceeded, the test will be marked as failed.")]
 
        // The EnabledIf attribute allows for disabling/hiding elements based on the value of other items.
        // Here the MaxAmplitude editor is disable if the LimitCheckEnabled property is true.
        // You can find more examples in the Plugin Development\TestSteps\Attributes section.
        [EnabledIf("LimitCheckEnabled", true, HideIfDisabled = true)]
        public double MaxAmplitude { get; set; } 
 
        #endregion
        
        public MeasurePeakAmplitudeTestStep()
        {
            // Default values for settings should be defined in the constructor.
            LimitCheckEnabled = true;
            MaxAmplitude = 50;
            InputData = new double[] {0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0};
            WindowSize = 3;
           
            // Validation Rules can be defined in the constructor to restrict the user inputs.
            Rules.Add(() => WindowSize > 0, "Window size must be greater than zero", "WindowSize");
            Rules.Add(SizesAreAppropriate, "Input Data must be larger than window size", "WindowSize", "InputData");
        }
        
        //public override void PrePlanRun()
        //{
        //    // This method is called on all TestSteps at the START of TestPlan execution.
        //    // If no setup code is needed, this method can be removed.
        //    base.PrePlanRun();            
        //}
 
        public override void Run()
        {   
            // The Run method is where the main execution logic of a TestStep exists.
            // This is a required method.
            try
            {
                // Setup instrument.
                MyGenerator.SetInputData(InputData);
 
                // Setup DUT.
                MyFilter.WindowSize = WindowSize;
 
                // Execute logic for DUT and handle data from DUT.
                ReadOnlyOutputData = MyFilter.CalcMovingAverage(InputData);
 
                // Check to see if limit checking is enabled.  If so, Upgrade the verdict.
                if (LimitCheckEnabled)
                {
                    // The Verdict is used by TAP to convey the general execution result of a Test Step.
                    UpgradeVerdict(ReadOnlyOutputData.Max() >= MaxAmplitude ? Verdict.Fail : Verdict.Pass);
                }
                else
                {
                    // All Test Steps have a standard Log object (inherited from the base class) 
                    // that can be used to write messages to the run log and the session log.
                    Log.Debug("Limit checking was not enabled.  This is why the verdict is inconclusive.");
                    UpgradeVerdict(Verdict.Inconclusive);
                }
 
                // Different log message types can be used based on what is being written.
                Log.Info("The DUT comment is {0}", MyFilter.Comment);
 
                // All Test Steps also contain a Results object. Results are store by calling Publish or PublishTable.
                Results.PublishTable("Inputs Versus Moving Average", new List<string>() {"Input Values", "Output Values"}, 
                    InputData, ReadOnlyOutputData);
            }
            catch (Exception ex)
            {   
                Log.Error(ex.Message);
 
                // The verdict can be set more than once in a Test Step.
                // UpgradeVerdict sets the current verdict to the more serious verdict.
                // If the new Verdict is not more severe, the original setting will be kept.
                UpgradeVerdict(Verdict.Error);
            }
        }
 
        //public override void PostPlanRun()
        //{
        //    // This method is called on all TestSteps at the END of TestPlan execution.
        //    // If no shutdown code is needed, this method can be removed.
        //    base.PostPlanRun();
        //}
 
        // Additional methods can be added to Test Step classes.
        private bool SizesAreAppropriate()
        {
            return InputData.Length > WindowSize;
        }
    }
}