/// <summary>
        /// Calculates the Undershoot related values
        /// </summary>
        /// <param name="undershootMaxTimeFWHMMultiplier">(Optional) The multiplier of the FWHM time to determine how long after the peak current time to search for undershoot (Default: 2.5x)</param>
        private void CalculateUndershoot(double undershootMaxTimeFWHMMultiplier = 2.5)
        {
            if (undershootMaxTimeFWHMMultiplier <= 0)
            {
                throw new ArgumentOutOfRangeException("The Undershoot Max Time multiplier cannot be less than or equal to 0");
            }

            // Determine how much time after the max data point of the waveform to keep for Undershoot
            double timeForUndershootDetectionAfterMaxTime = this.FullWidthHalfMaxValue * undershootMaxTimeFWHMMultiplier;

            // Add the undershoot allowed time to the max data point time
            double endTimeForUndershootDetection = this.PeakCurrentDataPoint.X + timeForUndershootDetectionAfterMaxTime;

            // Trim the waveform, removing everything before the max peak
            Waveform absoluteWaveformAfterPeakCurrentTime = this.AbsoluteWaveform.TrimStart(this.PeakCurrentDataPoint.X);

            // Trim the end of the waveform from the max time until 2.5x the FWHM time
            Waveform absoluteUndershootApplicableWaveform = absoluteWaveformAfterPeakCurrentTime.TrimEnd(endTimeForUndershootDetection);

            // Find the (absolute) undershoot data point of the absolute Current waveform after the max time
            DataPoint absoluteUndershootDataPoint = absoluteUndershootApplicableWaveform.Minimum();

            // Look up what the undershoot max percent can be (it is a negative value)
            this.UndershootAllowedMaximumPercent = CDMJS002WaveformCharacteristics.UndershootMaxPercent(this.SignedVoltage, this.IsLargeTarget, this.OscilloscopeIsHighBandwidth);

            // Calculate what the maximum undershoot value can be (it is a negative number since we are referring to undershoot)
            this.UndershootAllowedMaximumValue = this.PeakCurrentValue * this.UndershootAllowedMaximumPercent;

            // Convert the absolute undershoot value to the signed value
            double absoluteUndershootValue = absoluteUndershootDataPoint.Y;

            // If the absolute undershoot is greater than zero, set it to zero.  Otherwise set it to the signed value
            if (absoluteUndershootValue > 0)
            {
                this.UndershootValue = 0;
            }
            else
            {
                this.UndershootValue = absoluteUndershootValue.InvertValueIfNegativePolarity(this.WaveformIsPositivePolarity);
            }

            // Determine if the Undershoot is passing
            if (this.WaveformIsPositivePolarity)
            {
                this.UndershootIsPassing = this.UndershootValue >= this.UndershootAllowedMaximumValue;
            }
            else
            {
                this.UndershootIsPassing = this.UndershootValue <= this.UndershootAllowedMaximumValue;
            }

            // Create the undershoot signed Data Point
            this.UndershootDataPoint = absoluteUndershootDataPoint.InvertYValueIfNegativePolarity(this.WaveformIsPositivePolarity);
        }
Пример #2
0
        /// <summary>
        /// Calculates the Ring as a % of Ips
        /// </summary>
        private void CalculateRing()
        {
            double positiveLeadingEdgeNoiseValue = 0;
            double negativeLeadingEdgeNoiseValue = 0;

            if (this.compensateForNoise)
            {
                // (R&D experiment) A flag indicating that the noise reduction should use the peak-to-peak found in the zero line
                bool useZeroLineStrategy = true;

                // (R&D experiment) A flag indicating that the noise reduction should use a bessel-filtered waveform to remove the noise
                bool useBesselFilterStrategy = false;

                if (useZeroLineStrategy)
                {
                    Waveform zeroLineBeforeTriggerWaveform = this.AbsoluteWaveform.TrimEnd(this.compensateForNoiseCutoffTime);
                    positiveLeadingEdgeNoiseValue = zeroLineBeforeTriggerWaveform.Maximum().Y;
                    negativeLeadingEdgeNoiseValue = zeroLineBeforeTriggerWaveform.Minimum().Y;
                }
                else if (useBesselFilterStrategy)
                {
                    Waveform rawWaveform    = this.AbsoluteIpsPlusPeakCurrentDerivationOffsetWaveform;
                    Waveform besselWaveform = BesselDigitalFilter.FilterWaveform(rawWaveform);
                    for (int i = 0; i < rawWaveform.DataPoints.Count(); i++)
                    {
                        positiveLeadingEdgeNoiseValue = System.Math.Max(positiveLeadingEdgeNoiseValue, rawWaveform.DataPoints.ElementAt(i).Y - besselWaveform.DataPoints.ElementAt(i).Y);
                        negativeLeadingEdgeNoiseValue = System.Math.Min(negativeLeadingEdgeNoiseValue, rawWaveform.DataPoints.ElementAt(i).Y - besselWaveform.DataPoints.ElementAt(i).Y);
                    }
                }
            }

            // Find Ring1 Data point (max positive ring)
            this.Ring1PeakDataPoint = this.AbsoluteIpsPlusPeakCurrentDerivationOffsetWaveform.DataPointAtHBM0OhmJS001MaximumRing(this.AbsoluteIpsPolynomial, positiveLeadingEdgeNoiseValue, true);

            // Find Y-value of FifthDegreePolynomial at the time of Ring1
            double positiveRingLeastSquaresFitValue = this.AbsoluteIpsPolynomial.Evaluate(this.Ring1PeakDataPoint.X);

            // Find the difference between Ring1 and Ring1FDP
            double positiveRingCurrentDifference = this.Ring1PeakDataPoint.Y - positiveRingLeastSquaresFitValue;

            // Find the absolute value of the difference between Ring1 and Ring1FDP
            double positiveRingCurrentDifferenceAbs = System.Math.Abs(positiveRingCurrentDifference);

            // Find Ring2 Data point (max negative ring)
            this.Ring2PeakDataPoint = this.AbsoluteIpsPlusPeakCurrentDerivationOffsetWaveform.DataPointAtHBM0OhmJS001MaximumRing(this.AbsoluteIpsPolynomial, negativeLeadingEdgeNoiseValue, false);

            // Output the Ring2 DataPoint (max negative ring)

            // Find Y-value of FifthDegreePolynomial at the time of Ring2
            double negativeRingLeastSquaresFitValue = this.AbsoluteIpsPolynomial.Evaluate(this.Ring2PeakDataPoint.X);

            // Find the difference between Ring2 and Ring2FDP
            double negativeRingCurrentDifference = this.Ring2PeakDataPoint.Y - negativeRingLeastSquaresFitValue;

            // Find the absolute value of the difference between Ring2 and Ring2FDP
            double negativeRingCurrentDifferenceAbs = System.Math.Abs(negativeRingCurrentDifference);

            // Add the two differences to get Ir
            double totalRingCurrent = positiveRingCurrentDifferenceAbs + negativeRingCurrentDifferenceAbs;

            // Determine the ringing % compared to Ips
            this.TotalRingPercentValue = totalRingCurrent / System.Math.Abs(this.PeakCurrentValue);

            // Determine whether the ringing % is passing
            this.TotalRingIsPassing = this.TotalRingPercentValue <= this.TotalRingAllowedMaximum;
        }