/// <summary> /// Calculates the Decay Time related values /// </summary> private void CalculateDecayTime() { // The percentage of the Peak Current to be the end of the decay time (1/e) double decayTimeEndPercentOfIps = 1.0 / System.Math.E; // Trim the waveform, removing everything before the max peak Waveform absoluteWaveformAfterPeakCurrentTime = this.AbsoluteWaveform.TrimStart(this.PeakCurrentDataPoint.X); // Find the start/stop times for the noise-reducing exponential fit waveform DataPoint?expFitStartDataPoint = absoluteWaveformAfterPeakCurrentTime.DataPointAtYThreshold(0.5 * System.Math.Abs(this.PeakCurrentValue), true); if (expFitStartDataPoint.HasValue) { double expFitStartTimeThreshold = expFitStartDataPoint.Value.X; DataPoint?expFitEndDataPoint = absoluteWaveformAfterPeakCurrentTime.DataPointAtYThreshold(0.3 * System.Math.Abs(this.PeakCurrentValue), true); // The waveform was truncated before the lower end of the decaying region, // however there might be enough data to calculate by using the last data point instead. if (!expFitEndDataPoint.HasValue) { expFitEndDataPoint = absoluteWaveformAfterPeakCurrentTime.DataPoints.Last(); } double expFitEndTimeThreshold = expFitEndDataPoint.Value.X; // Gate the waveform to just the area for the noise-reducing exponential fit waveform Waveform absoluteWaveformDecayingRegion = this.AbsoluteWaveform.Gates(expFitStartTimeThreshold, expFitEndTimeThreshold); if (absoluteWaveformDecayingRegion.DataPoints.Any()) { // Find the exponential fit constants of the waveform from 0.5 * Ips to 0.3 * Ips to eliminate noise Tuple <double, double> expFitAbsoluteWaveformDecayingRegionConstants = absoluteWaveformDecayingRegion.ExponentialFit(); // Create time values that go out far enough to ensure the decay time end threshold can be found List <double> timeValues = (from dp in absoluteWaveformDecayingRegion.DataPoints select dp.X).ToList(); double samplingTime = absoluteWaveformDecayingRegion.SamplingTime(); while (timeValues.Last() < 0.000000800 && samplingTime > 0) { timeValues.Add(timeValues.Last() + samplingTime); } // Create the exponential fit equivalent waveform which has noise eliminated Waveform expFitAbsoluteWaveformDecayingRegion = WaveformExtensions.CreateExponentialFitWaveform( expFitAbsoluteWaveformDecayingRegionConstants.Item1, expFitAbsoluteWaveformDecayingRegionConstants.Item2, timeValues); // Calculate what the decay time end threshold is (1/e % of Ips) double decayTimeEndThreshold = System.Math.Abs(this.PeakCurrentValue) * decayTimeEndPercentOfIps; // Find the first (interpolated) data point that is at 1/e % of Ips value (of the absolute value waveform) DataPoint?decayTimeEndDataPointAbsolute = expFitAbsoluteWaveformDecayingRegion.DataPointAtYThreshold(decayTimeEndThreshold, true); if (decayTimeEndDataPointAbsolute.HasValue) { // Convert the Decay Time end DataPoint to the signed value this.DecayTimeEndDataPoint = decayTimeEndDataPointAbsolute.Value.InvertYValueIfNegativePolarity(this.WaveformIsPositivePolarity); // Calculate the Decay Time this.DecayTimeValue = this.DecayTimeEndDataPoint.X - this.PeakCurrentDataPoint.X; // Determine if the Decay Time is passing this.DecayTimeIsPassing = DoubleRangeExtensions.BetweenInclusive(this.DecayTimeAllowedMinimum, this.DecayTimeAllowedMaximum, this.DecayTimeValue); } else { // The derived exponential fit waveform didn't go out to a far enough time to capture the 1/e time. } } else { // Could not find any data points in the decay time window. Likely due to a malformed waveform. } } else { // Since the waveform was truncated before even the start of the window to calculate the decaying region, the decay time cannot be calculated. } }
public void ExponentialFitTest() { Waveform input = new Waveform(new List <DataPoint>() { new DataPoint(0.0000001000, 0.07383999), new DataPoint(0.0000001008, 0.08215999), new DataPoint(0.0000001016, 0.08215999), new DataPoint(0.0000001024, 0.08215999), new DataPoint(0.0000001032, 0.09463999), new DataPoint(0.0000001040, 0.08215999), new DataPoint(0.0000001048, 0.08631999), new DataPoint(0.0000001056, 0.09047999), new DataPoint(0.0000001064, 0.07799999), new DataPoint(0.0000001072, 0.07799999), new DataPoint(0.0000001080, 0.08631999), new DataPoint(0.0000001088, 0.07799999), new DataPoint(0.0000001096, 0.06967999), new DataPoint(0.0000001104, 0.08631999), new DataPoint(0.0000001112, 0.08215999), new DataPoint(0.0000001120, 0.08631999), new DataPoint(0.0000001128, 0.07799999), new DataPoint(0.0000001136, 0.06967999), new DataPoint(0.0000001144, 0.07383999), new DataPoint(0.0000001152, 0.08215999), new DataPoint(0.0000001160, 0.06967999), new DataPoint(0.0000001168, 0.08215999), new DataPoint(0.0000001176, 0.06967999), new DataPoint(0.0000001184, 0.07799999), new DataPoint(0.0000001192, 0.06967999), new DataPoint(0.0000001200, 0.07383999), new DataPoint(0.0000001208, 0.07383999), new DataPoint(0.0000001216, 0.07383999), new DataPoint(0.0000001224, 0.07383999), new DataPoint(0.0000001232, 0.07799999), new DataPoint(0.0000001240, 0.06967999), new DataPoint(0.0000001248, 0.06967999), new DataPoint(0.0000001256, 0.07799999), new DataPoint(0.0000001264, 0.07799999), new DataPoint(0.0000001272, 0.07383999), new DataPoint(0.0000001280, 0.07799999), new DataPoint(0.0000001288, 0.06967999), new DataPoint(0.0000001296, 0.08215999), new DataPoint(0.0000001304, 0.06967999), new DataPoint(0.0000001312, 0.07383999), new DataPoint(0.0000001320, 0.07799999), new DataPoint(0.0000001328, 0.06551999), new DataPoint(0.0000001336, 0.06967999), new DataPoint(0.0000001344, 0.07383999), new DataPoint(0.0000001352, 0.06551999), new DataPoint(0.0000001360, 0.06551999), new DataPoint(0.0000001368, 0.07383999), new DataPoint(0.0000001376, 0.07383999), new DataPoint(0.0000001384, 0.07799999), new DataPoint(0.0000001392, 0.07383999), new DataPoint(0.0000001400, 0.06135999), new DataPoint(0.0000001408, 0.06551999), new DataPoint(0.0000001416, 0.07383999), new DataPoint(0.0000001424, 0.07383999), new DataPoint(0.0000001432, 0.06967999), new DataPoint(0.0000001440, 0.06551999), new DataPoint(0.0000001448, 0.06135999), new DataPoint(0.0000001456, 0.06551999), new DataPoint(0.0000001464, 0.06551999), new DataPoint(0.0000001472, 0.05719999), new DataPoint(0.0000001480, 0.06135999), new DataPoint(0.0000001488, 0.06967999), new DataPoint(0.0000001496, 0.05719999), new DataPoint(0.0000001504, 0.06135999), new DataPoint(0.0000001512, 0.06967999), new DataPoint(0.0000001520, 0.06967999), new DataPoint(0.0000001528, 0.07383999), new DataPoint(0.0000001536, 0.06135999), new DataPoint(0.0000001544, 0.06967999), new DataPoint(0.0000001552, 0.06551999), new DataPoint(0.0000001560, 0.06135999), new DataPoint(0.0000001568, 0.06135999), new DataPoint(0.0000001576, 0.05719999), new DataPoint(0.0000001584, 0.06967999), new DataPoint(0.0000001592, 0.04887999), new DataPoint(0.0000001600, 0.05719999), new DataPoint(0.0000001608, 0.06135999), new DataPoint(0.0000001616, 0.06135999), new DataPoint(0.0000001624, 0.04887999), new DataPoint(0.0000001632, 0.05303999), new DataPoint(0.0000001640, 0.05303999), new DataPoint(0.0000001648, 0.04887999), new DataPoint(0.0000001656, 0.06551999), new DataPoint(0.0000001664, 0.05303999), new DataPoint(0.0000001672, 0.05303999), new DataPoint(0.0000001680, 0.05303999), new DataPoint(0.0000001688, 0.05303999), new DataPoint(0.0000001696, 0.05719999), new DataPoint(0.0000001704, 0.06135999), new DataPoint(0.0000001712, 0.05303999), new DataPoint(0.0000001720, 0.04471999), }); Waveform expected = new Waveform(new List <DataPoint>() { new DataPoint(0.0000001000, 0.085970021), new DataPoint(0.0000001008, 0.085540831), new DataPoint(0.0000001016, 0.085113783), new DataPoint(0.0000001024, 0.084688868), new DataPoint(0.0000001032, 0.084266074), new DataPoint(0.0000001040, 0.08384539), new DataPoint(0.0000001048, 0.083426807), new DataPoint(0.0000001056, 0.083010313), new DataPoint(0.0000001064, 0.082595899), new DataPoint(0.0000001072, 0.082183553), new DataPoint(0.0000001080, 0.081773266), new DataPoint(0.0000001088, 0.081365028), new DataPoint(0.0000001096, 0.080958827), new DataPoint(0.0000001104, 0.080554654), new DataPoint(0.0000001112, 0.080152499), new DataPoint(0.0000001120, 0.079752352), new DataPoint(0.0000001128, 0.079354202), new DataPoint(0.0000001136, 0.07895804), new DataPoint(0.0000001144, 0.078563856), new DataPoint(0.0000001152, 0.07817164), new DataPoint(0.0000001160, 0.077781382), new DataPoint(0.0000001168, 0.077393072), new DataPoint(0.0000001176, 0.077006701), new DataPoint(0.0000001184, 0.076622258), new DataPoint(0.0000001192, 0.076239735), new DataPoint(0.0000001200, 0.075859122), new DataPoint(0.0000001208, 0.075480408), new DataPoint(0.0000001216, 0.075103586), new DataPoint(0.0000001224, 0.074728644), new DataPoint(0.0000001232, 0.074355575), new DataPoint(0.0000001240, 0.073984368), new DataPoint(0.0000001248, 0.073615014), new DataPoint(0.0000001256, 0.073247504), new DataPoint(0.0000001264, 0.072881828), new DataPoint(0.0000001272, 0.072517979), new DataPoint(0.0000001280, 0.072155946), new DataPoint(0.0000001288, 0.07179572), new DataPoint(0.0000001296, 0.071437292), new DataPoint(0.0000001304, 0.071080654), new DataPoint(0.0000001312, 0.070725796), new DataPoint(0.0000001320, 0.07037271), new DataPoint(0.0000001328, 0.070021387), new DataPoint(0.0000001336, 0.069671818), new DataPoint(0.0000001344, 0.069323993), new DataPoint(0.0000001352, 0.068977905), new DataPoint(0.0000001360, 0.068633545), new DataPoint(0.0000001368, 0.068290905), new DataPoint(0.0000001376, 0.067949974), new DataPoint(0.0000001384, 0.067610746), new DataPoint(0.0000001392, 0.067273211), new DataPoint(0.0000001400, 0.066937362), new DataPoint(0.0000001408, 0.066603189), new DataPoint(0.0000001416, 0.066270684), new DataPoint(0.0000001424, 0.065939839), new DataPoint(0.0000001432, 0.065610646), new DataPoint(0.0000001440, 0.065283097), new DataPoint(0.0000001448, 0.064957182), new DataPoint(0.0000001456, 0.064632895), new DataPoint(0.0000001464, 0.064310227), new DataPoint(0.0000001472, 0.063989169), new DataPoint(0.0000001480, 0.063669714), new DataPoint(0.0000001488, 0.063351855), new DataPoint(0.0000001496, 0.063035582), new DataPoint(0.0000001504, 0.062720888), new DataPoint(0.0000001512, 0.062407765), new DataPoint(0.0000001520, 0.062096205), new DataPoint(0.0000001528, 0.0617862), new DataPoint(0.0000001536, 0.061477744), new DataPoint(0.0000001544, 0.061170827), new DataPoint(0.0000001552, 0.060865442), new DataPoint(0.0000001560, 0.060561582), new DataPoint(0.0000001568, 0.060259239), new DataPoint(0.0000001576, 0.059958406), new DataPoint(0.0000001584, 0.059659074), new DataPoint(0.0000001592, 0.059361236), new DataPoint(0.0000001600, 0.059064886), new DataPoint(0.0000001608, 0.058770015), new DataPoint(0.0000001616, 0.058476616), new DataPoint(0.0000001624, 0.058184682), new DataPoint(0.0000001632, 0.057894205), new DataPoint(0.0000001640, 0.057605178), new DataPoint(0.0000001648, 0.057317595), new DataPoint(0.0000001656, 0.057031447), new DataPoint(0.0000001664, 0.056746727), new DataPoint(0.0000001672, 0.056463429), new DataPoint(0.0000001680, 0.056181545), new DataPoint(0.0000001688, 0.055901069), new DataPoint(0.0000001696, 0.055621993), new DataPoint(0.0000001704, 0.05534431), new DataPoint(0.0000001712, 0.055068013), new DataPoint(0.0000001720, 0.054793096), }); Tuple <double, double> constants = input.ExponentialFit(); Waveform actual = WaveformExtensions.CreateExponentialFitWaveform(constants.Item1, constants.Item2, from dp in input.DataPoints select dp.X); Assert.AreEqual(input.DataPoints.Count(), expected.DataPoints.Count()); Assert.AreEqual(input.DataPoints.Count(), actual.DataPoints.Count()); for (int i = 0; i < input.DataPoints.Count(); i++) { Assert.AreEqual(expected.DataPoints.ElementAt(i).Y, actual.DataPoints.ElementAt(i).Y, 0.000001); } }