Beispiel #1
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;
        }
        /// <summary>
        /// Returns a new waveform that has been filtered using the Bessel algorithm.
        /// </summary>
        /// <param name="waveform">The original waveform.</param>
        /// <returns>The Bessel filtered waveform.</returns>
        internal static Waveform FilterWaveform(Waveform waveform)
        {
            // If there are not more than 3 data points, then no bessel filtering can occur
            if (waveform == null || waveform.DataPoints.Count() <= 3)
            {
                return(new Waveform(waveform.DataPoints));
            }

            double samplingFrequency = waveform.SamplingFrequency();

            int paddingCount = 3;

            List <DataPoint> inputDataPoints = new List <DataPoint>(waveform.DataPoints);

            // The filter should be started in the prepulse noise with y[0]=y[1]=y[2]=average of (x[0],x[1],x[2]).
            double paddingY = 0.0;

            for (int i = 0; i < paddingCount; i++)
            {
                paddingY += inputDataPoints[i].Y;
            }

            paddingY = paddingY / (double)paddingCount;
            for (int i = 0; i < paddingCount; i++)
            {
                inputDataPoints.Insert(0, new DataPoint(inputDataPoints[0].X, paddingY));
            }

            List <DataPoint> outputDataPoints = new List <DataPoint>(inputDataPoints.Count);

            Tuple <double, double, double, double, int> coefficientSet = BesselDigitalFilter.GetCorrectSamplingCoefficientSet(samplingFrequency);
            double a1    = coefficientSet.Item1;
            double a3    = coefficientSet.Item1 * 3.0;
            double b     = coefficientSet.Item2;
            double c     = coefficientSet.Item3;
            double d     = coefficientSet.Item4;
            int    delay = coefficientSet.Item5;

            // Calculate how much each datapoint's X value must be shifted by
            double horizontalShift = (1 / samplingFrequency) * delay * -1;

            for (int n = 0; n < inputDataPoints.Count; n++)
            {
                DataPoint newDataPoint;
                if (n < 3)
                {
                    newDataPoint = new DataPoint(inputDataPoints[n].X + horizontalShift, inputDataPoints[n].Y);
                }
                else
                {
                    double y =
                        (a1 * inputDataPoints[n - 3].Y) +
                        (a3 * inputDataPoints[n - 2].Y) +
                        (a3 * inputDataPoints[n - 1].Y) +
                        (a1 * inputDataPoints[n - 0].Y) +
                        (b * outputDataPoints[n - 3].Y) +
                        (c * outputDataPoints[n - 2].Y) +
                        (d * outputDataPoints[n - 1].Y);

                    newDataPoint = new DataPoint(inputDataPoints[n].X + horizontalShift, y);
                }

                outputDataPoints.Add(newDataPoint);
            }

            // Remove the 3 data points that were padding to get the digital filter started
            outputDataPoints.RemoveRange(0, paddingCount);

            return(new Waveform(outputDataPoints));
        }