Issue with auto find peaks

I have a large data set of intensity vs time and want to find the maximum peak values. When I do the auto peak find function, it sometimes gives an average max based on a box I think (so it averages between five points and gives that average and not the actual max). I was trying to alter 741's code (See examples below) but it still gives me a similar problem where the calculated maxima are randomly not actual maxima, but averaged values. Is there something I'm missing?

Function FindLocalPeaks(data)
    wave data    // wave containing the trace to analyze
    variable nPoints = DimSize(data, 0)
 
    Make /N=(nPoints) /O PeakName = 0   // PeakName is guaranteed to have too many points
                                        // since there can never be as many peaks as there are points in the data
 
    variable i
    for (i = 1; i < nPoints - 1; i+=1)
        if ((data[i - 1] < data[i]) && (data[i] > data[i+1]))
            // the point at index i is a local peak
            PeakName[i] = data[i]
            offset += 1
        endif
    endfor
 

End



So if my csv is:
timeW Intensity
3460473540 350
3460473600 350
3460473660 337
3460473720 320
3460473780 297
3460473840 298
3460473900 1246
3460473960 13776
3460474020 1546
3460474080 1398
3460474140 1097
3460474200 699
3460474260 616
3460474320 427
3460474380 376
3460474440 343
3460474500 327

I want a new wave to be:
3460473540 0
3460473600 0
3460473660 0
3460473720 0
3460473780 0
3460473840 0
3460473900 0
3460473960 13776
3460474020 0
3460474080 0
3460474140 0
3460474200 0
3460474260 0
3460474320 0
3460474380 0
3460474440 0
3460474500 0

And at long datasets, it randomly gives:
... ...
3460473540 0
3460473600 0
3460473660 0
3460473720 0
3460473780 0
3460473840 0
3460473900 0
3460473960 6000
3460474020 0
3460474080 0
3460474140 0
3460474200 0
3460474260 0
3460474320 0
3460474380 0
3460474440 0
3460474500 0
... ...

I found a "fix" but its not ideal as it takes a while to process. I use Wavestat to get the maximum and put it into a wave. Any ideas on how to do this with only V-max and not all the "V" stats?

Function FindLocalPeaks(data)
    wave data    // wave containing the trace to analyze
    variable nPoints = DimSize(data, 0)
 
    Make /N=(nPoints) /O PeakName = 0   // PeakName is guaranteed to have too many points
                                        // since there can never be as many peaks as there are points in the data
 
    variable i
    for (i = 1; i < nPoints - 1; i+=1)
        WaveStats/R=[i-10,i+10] data
        If (v_max==data[i])
        PeakName[i]=data[i]
       // i+=1
       
        else
        PeakName[i]=0
        //i+=1
       
        endif
   
    endfor

End
chemgoof wrote:
I have a large data set of intensity vs time and want to find the maximum peak values.

....

timeW Intensity
3460473540 0
3460473600 0
3460473660 0
3460473720 0
3460473780 0
3460473840 0
3460473900 0
3460473960 13776
3460474020 0
3460474080 0
3460474140 0
3460474200 0
3460474260 0
3460474320 0
3460474380 0
3460474440 0
3460474500 0


If you want the output wave to have the peak value at at the actual position of the peak max and be zero elsewhere (as shown above) then try the following modification

Function FindLocalPeaks(data)
    wave data    // wave containing the trace to analyze

   variable nPoints = DimSize(data, 0)

 //   Duplicate /O data, PeakName = 0  incorrect syntax
    Duplicate /O data, PeakName  
   PeakName = 0
                                       
    variable i
    for (i = 1; i < nPoints - 2; i+=1)
        if ((data[i - 1] < data[i]) && (data[i] > data[i+1]))
            // the point at index i is a local peak
            PeakName[i] = data[i]
//next two lines are not needed if PeakName is already set to 0
//        else
 //           PeakName[i] = 0
        endif
    endfor

End


Two problems that occur to me are that you will miss local maxima at the first and last points in the wave and, if your data is noisey there will be many peaks found that you may not want to consider as peaks.

Edit 9/25:
The function above was edited to correct a syntax error and a few other changes resulted because of that.

Here is a function that does the same thing usint the ?: construct.

Function FindLocalPeaks_1(data)
    wave data    // wave containing the trace to analyze
 
    variable nPoints = DimSize(data, 0)
 
    Duplicate /O data, PeakName
    PeakName = 0
    PeakName[1,nPoints -2] = (data[p - 1] < data[p]) && (data[p] > data[p+1]) ? data[p] : 0
   
End


Again, with both of these functions, local maxima at the first and last points will be missed. If this is critical, you will need to add code to handle those cases.
You can use WaveStats/Q/M=1

The /Q flag suppresses the history report (which takes a lot of execution time) and /M=1 request just the simple stuff be calculated.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com