LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Peak detection algorithm without inbuilt vi

I'm creating an automated peak detection and analysis vi, but I am unable to use inbuilt vis eg peak detector.vi. I have created a peak detection algorithm using array max and min point by point in a for loop, but it isn't the most accurate method and detecting the location of the peak doesn't work too well this way, especially for noisy signals. Does anyone have a good idea on a method to use?

Thank you

0 Kudos
Message 1 of 9
(4,169 Views)

What is your data? 

 

If your data is f(x) then calculus is your friend here.   You can use first and second derivatives to find local maxima and minima.  (See - https://www.mathsisfun.com/calculus/maxima-minima.html or that old differential calculus text book.)

 

You will still need to do some work to set thresholds for determining peaks from the noise, how many peaks in a certain range, etc.

 

if your data is just random and you need to find N maxima then you could use the Array Min/Max function to extract the N largest values.  Or sort array and take first N values.  Array Min/Max gives you the indices of the Max/Min which is nice.

 

Craig

0 Kudos
Message 2 of 9
(4,142 Views)

Thank you Craig,

 

My data is effectively f(x) (more specifically, the spectrum produced by High Pressure Liquid Chromatography).

 

The method I’m currently using is based on array max and min, it’s ok for cleaner data and no peaks that are situated close to each other, but as soon as you get double peaks, it’s struggles and will only detect the larger of the two.

 

I have toyed around with using the derivatives but I haven’t had much success in actually implementing the code itself and building an array of peaks. Do you have any suggestions of how to do this? I feel it could be the best alternative actually coding this method is more difficult I have found.

0 Kudos
Message 3 of 9
(4,120 Views)

Have a look at the Savitzky-Golay filter

You can use it to get a smoothed derivate (search for the zero crossing) and is a common way to filter noisy spectra.

 

Never checked, but the peak detection work by fitting a square function over specified number <n> of points (see LV help) . If the SG-filter sidepoints <sp>  are set to

<n>=2*<sp>+1

and the SG filter order is 2 , you should get the same results.

 

But the SG filter allow to set the fit order. ( However for spectra a second order is very common )

Greetings from Germany
Henrik

LV since v3.1

“ground” is a convenient fantasy

'˙˙˙˙uıɐƃɐ lɐıp puɐ °06 ǝuoɥd ɹnoʎ uɹnʇ ǝsɐǝld 'ʎɹɐuıƃɐɯı sı pǝlɐıp ǝʌɐɥ noʎ ɹǝqɯnu ǝɥʇ'


0 Kudos
Message 4 of 9
(4,104 Views)

I’ll have a look at the Savitzky-Golay filter and see what effect it has. Would you perform a normal peak detection after this? And if so, would you have any recommendations of how without the use of the peak detector vi? My current method only works on very clean data which this filter may help (I have developed other smoothing too such as a Boxcar Average which does work quite well).

 

Danke für deine Hilfe!

0 Kudos
Message 5 of 9
(4,088 Views)

Writing a full blown fool proof  alternative to native LabVIEW functions is not something many people will take time to do. Peak fitting without the native functions would be a much bigger task!  (I'm not 100% clear on what VIs would be missing..)

 

Helping you find a solution to your problem might be possible however.  Share your code, and some raw data, and perhaps we can suggest improvements. Post some images of where you think its failing and highlight raw data.

 

Craig

 

 

0 Kudos
Message 6 of 9
(4,086 Views)

I have attached a clean signal and a trimmed version of the code used. It is split into 3 sections, importing data, a Boxcar average and the peak detection. The peak detection is based on array max and min point by point and followed by a loop to remove duplicate values.

You may see that the final peak of the 6 isn't detected as the large peak close by is picked up twice in two location. The output array gives amplitudes of the detected peaks, with the sample length affecting the peak detection (I set mine to 2). I set the boxcar width to 8 and threshold to 40 in this case.

I would like to be able to resolve the double peak better and detect the locations of the peaks.

 

Thank you for any advice possible,

Stephen

Download All
0 Kudos
Message 7 of 9
(4,081 Views)

Smells a lot like homework.  For Physics 341?

 

First, thinks will be easier if you spend a few hours going over the LabVIEW fundamentals:

- of plotting with XY graphs. 

     - No need to convert the data to dynamic and use waveforms graphs.  Arrays and X-Y plot are fine.

     - You can add multiple datasets to the same X-Y plot and see what points you've picked. 

- style and tidiness (wires flow left to right L-R, not U-D-R-L-U-L-R 😉

- auto-indexing For loops & using shift registers.

     - No need to initialize an array of the exact length, just use an empty array for Shift registers.

     - If you use auto-indexing then you can avoid Array Replace Subset when its not needed

- learn the array VIs. 

    - array indexing, no need to transpose and pick rows, just pick columns using the same VI!

- make subvis

- that whole block diagram should be easily visible in one monitor's width.

- See attached mild code clean-up, that SHOULD be much further cleaned up and simplified.

    - I left it as an exercise to include the peaks on the plot at the proper x positions. 😉

 

Now in terms of your coded as-is, I think it should work.  But why are you setting a threshold of 40? Once you average that data with 8 points the last peak drops below 40...and its not detected.  So set width to 4, threshold to 20 and BINGO you have 6 peaks.

 

 

0 Kudos
Message 8 of 9
(4,069 Views)

Don’t worry, it’s not homework! It’s bits and pieces from an old project that I’m trying I adapt and relearn for an upcoming report. The reason it’s a mess is because I’ve deleted a lot of unnecessary parts that ran parallel but haven’t cleaned it all up yet.

 

As far as the code goes, it still struggles in the very last peak but I’m thinking adding a condition based on the derivatives being zero in to try and help that.

 

I do like the way in which you have presented the data however, I find it helpful. I will try and improve the use of arrays in this case though, I get that I’ve over complicated some areas here

 

thank you,

Stephen

0 Kudos
Message 9 of 9
(4,053 Views)