Batch Automatically find peaks

Hi!

I'm probably being really stupid here, but I have over 1200 curves oscillating over a few cycles that are all collected on the same timebase. I want to identify all of the peaks in the data as a batch - both X (time of peak) and Y (amplitude of peak).

I've been able to get nice peak recognition using the Automatically Detect Peaks package, but this only allows me to identify peaks in one curve at a time. Ideally, I want to automate this and output the X and Y coordinates to separate tables with each column representing each individual curve. Does anyone have any ideas how to automate this?

Many Thanks,

Ander
Everyone wants to do this differently, in my experience, so no one solution has presented itself.

It is handy that Igor is completely programmable, so you can automate the procedure yourself, possibly with some help here.

To get that help, you'd need to upload an example of your data, the code you've already got (if you have any), and a clear description of what you want.

That "clear description" is the hard part; it is easy to believe that what one writes is necessarily exactly what the reader perceives.

--Jim Prouty
Software Engineer, WaveMetrics, Inc.
I might suggest these steps ...

* Write the code you need to load a data file.
* Write the code that does the work required to get the answers from that one data file.
* Put the two pieces of code in to a function with a loop over all the files that you want to process.

Is this the direction of the hints that you are after?

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH
I haven't used the Automatically Detect Peaks package, but the Multipeak Fitting 2 package under the Analysis-Packages menu may be able to do what you need. First check if it can do a good job without user intervention on a single data set just by trying "auto-locate peaks now" followed by "OK" and "do fit". If that result looks reasonable, take a look in the package's help where there's a batch fitting procedure near the end called MultiPeakBatchFit(datafoldername,ywavelist,xwavelist). It'll probably require some modification for your application.

DisplayHelpTopic("Multi-Peak Fitting for Igor Programmers")
Hi.
I once wrote a wrapper function for WM's PeakFind. Probably not the nicest solution but take a look at PeakFind() in https://github.com/ukos-git/igor-common-utilities/blob/master/app/utili…

#include <Peak AutoFind>

Function/Wave PeakFind(wavInput, [wvXdata, noiselevel, smoothingFactor, minPeakPercent, maxPeaks, verbose])
	Wave wavInput, wvXdata
	Variable noiselevel, smoothingFactor, minPeakPercent, maxPeaks
	variable verbose

	if (ParamIsDefault(verbose))
		verbose = 0
	endif

	Variable pBegin, pEnd
	Variable/C estimates

	Variable peaksFound
	String newName

	if(ParamIsDefault(wvXdata))
		Make/N=(DimSize(wavInput, 0))/Free wvXdata = DimOffset(wavInput, 0) + DimDelta(wavInput, 0) * p
	endif
	Wave wavYdata = wavInput

	Make/FREE/N=(maxPeaks,7) wavOutput

	// label columns of wave for readability
	SetDimLabel 1, 0, wavelength, wavOutput
	SetDimLabel 1, 1, height, wavOutput
	SetDimLabel 1, 2, width, wavOutput
	SetDimLabel 1, 3, positionY, wavOutput
	SetDimLabel 1, 4, positionX, wavOutput
	SetDimLabel 1, 5, widthL, wavOutput // from WM: somewhat free width left and right
	SetDimLabel 1, 6, widthR, wavOutput

	// input parameters for WM's AutoFindPeaksNew
	pBegin = 0
	pEnd = DimSize(wavYdata, 0) - 1

	if(ParamIsDefault(maxPeaks))
		maxPeaks = 10
	endif
	if(ParamIsDefault(minPeakPercent))
		minPeakPercent = 5
	endif
	if(ParamIsDefault(noiselevel))
		noiselevel = 1
	endif
	estimates = EstPeakNoiseAndSmfact(wavYdata, pBegin, pEnd)
	noiselevel *= real(estimates)
	if(ParamIsDefault(smoothingFactor))
		smoothingFactor = imag(estimates)
	endif
	if(!(noiselevel>0))
		noiselevel = 0.01
	endif

	peaksFound = AutoFindPeaksNew(wavYdata, pBegin, pEnd, noiseLevel, smoothingFactor, maxPeaks)
	WAVE W_AutoPeakInfo // output of AutoFindPeaksNew

	if(verbose > 2)
		print "== peakFind =="
		printf "peaks: \t %d\r", peaksFound
		printf "smooth: \t %.1f\r", smoothingFactor
		printf "noise: \t %.4f\r", noiseLevel
	endif

	// Remove too-small peaks
	if(peaksFound > 0)
		peaksFound = TrimAmpAutoPeakInfo(W_AutoPeakInfo,minPeakPercent/100)
	endif

	// process peaks
	if(peaksFound > 0)
		// Redimension to number of peaks
		Redimension/N=(peaksFound, -1) wavOutput

		// save peak positions in input wave
		wavOutput[][%positionX] = W_AutoPeakInfo[p][0]
		wavOutput[][%positionY] = wavYdata[wavOutput[p][%positionX]]

		// The x values in W_AutoPeakInfo are still actually points, not X
		AdjustAutoPeakInfoForX(W_AutoPeakInfo, wavYdata, wvXdata)
		wavOutput[][%wavelength]	 = W_AutoPeakInfo[p][0]

		// save all data from WM procedure
		wavOutput[][%width]		 = W_AutoPeakInfo[p][1]
		wavOutput[][%height]	 = W_AutoPeakInfo[p][2]
		wavOutput[][%widthL]	 = W_AutoPeakInfo[p][3]
		wavOutput[][%widthR]	 = W_AutoPeakInfo[p][4]
	endif

	return wavOutput
End

You could use this in a for loop over all of your waves. Just an example for fitting one wave:

Function testfit(center)
	variable center
	
	Make/FREE myPeak
	setscale x, -10, 10, myPeak
	myPeak = gauss(x,center,1) + gnoise(0.02)
	
	WAVE peakresults = peakfind(myPeak)
	print peakresults[0][%wavelength], peakresults[0][%height]
End


Automatically Find Peaks is using the second derivative for peakfind. You should do a fit in addition after the "initial values" were found using peakfind. If you consider a PeakFit take a look at https://github.com/ukos-git/igor-common-utilities/blob/master/app/utili…. I implemented the Gauss Fit from the MultiPeak Fit package.