14.3 Savitzky-Golay Peak Finding (.NET, C#, CSharp, VB, Visual Basic, F#)
Class PeakFinderSavitzkyGolay uses smooth Savitzky-Golay derivatives to find peaks in data. A peak is defined as a smoothed derivative zero crossing.
PeakFinderSavitzkyGolay extends PeakFinderBase, the abstract base class for all peak finding algorithms, and an enumerable collection of all found peaks.
Creating Savitzky-Golay Peak Finders
A PeakFinderSavitzkyGolay instance is constructed from a vector of data, a window width, and the degree of polynomial used to fit the data. For instance, this code builds a data set from a sinc() function, then constructs a peak finder with a width of 6, and 4th degree smoothing polynomial:
Code Example – C# peak finding
var x = new DoubleVector(5000, 0.01, 0.1);
DoubleVector data = NMathFunctions.Sin(x) / x;
PeakFinderSavitzkyGolay pf =
new PeakFinderSavitzkyGolay(data, 6, 4);
Code Example – VB peak finding
Dim X As New DoubleVector(5000, 0.01, 0.1)
Dim Data As DoubleVector = NMathFunctions.Sin(X) / X
Dim PF As New PeakFinderSavitzkyGolay(Data, 6, 4)
The constructor parameters must satisfy the following rules:
● The window width must be less than the length of the data.
● The polynomial degree must be less than the window width.
Typically, the degree of the smoothing polynomial is between 3 and 5.
Savitzky-Golay Peak Finder Results
Once you've constructed a PeakFinderSavitzkyGolay object, the LocatePeaks() method finds all peak abscissae and their smoothed ordinates in current data set:
Code Example – C# peak finding
pf.LocatePeaks();
Code Example – VB peak finding
PF.LocatePeaks()
The provided indexer on PeakFinderSavitzkyGolay gets each peak as an instance of struct Extrema. Property NumberPeaks gets the total number of peaks found. For example, this code dump all peaks to the console:
Code Example – C# peak finding
for (int i = 0; i < pf.NumberPeaks; i++)
{
Extrema peak = pf[i];
Console.WriteLine("Found peak at = ({0},{1})", peak.X, peak.Y);
}
Code Example – VB peak finding
For I As Integer = 0 To PF.NumberPeaks - 1
Dim Peak As Extrema = PF(I)
Console.WriteLine("Found peak at = ({0},{1})", Peak.X, Peak.Y)
Next
Advanced Savitzky-Golay Peak Finder Properties
Additional properties on PeakFinderSavitzkyGolay control the set of peaks that are found by the LocatePeaks() method:
● SlopeSelectivity gets and sets the slope selectivity. The selectivity of the peak finder can be reduced by increasing the SlopeSelectivity. If SlopeSelectivity is set to 0 (default), all found peaks are reported.
● AbscisaInterval gets and sets the abscissa interval for the data. This is used to scale the derivatives to the correct units. For proper scaling of the peak abscissa locations, set AbscissaInterval to the data sample interval.
● RootFindingTolerance gets and sets the error tolerance for the underlying RiddersRootFinder. The default is 0.00001.
For instance:
Code Example – C# peak finding
pf.AbscissaInterval = 0.1;
pf.SlopeSelectivity = 0;
pf.LocatePeaks();
Code Example – VB peak finding
PF.AbscissaInterval = 0.1
PF.SlopeSelectivity = 0
PF.LocatePeaks()