1.12.5 Peaks and Baseline


Getting input XY from Graph or Worksheet

For the input XY data the following sections mentioned, we can get from Graph or Worksheet. Please click here to get the help of getting data from window.

Creating a Baseline

The ocmath_create_baseline_by_masking_peaks function can create a baseline according to only positive peaks, only negative peaks, or both direction peaks.

The following example shows how to create a baseline for the positive peaks and the negative peaks in input XY data(vx, vy).

// Allocate memory for baseline XY vectors
vector vxBaseline(vx.GetSize()), vyBaseline(vx.GetSize());

// find baseline XY data
int nRet = ocmath_create_baseline_by_masking_peaks(vx.GetSize(), vx, vy, 
	vxBaseline.GetSize(), vxBaseline, vyBaseline, BOTH_DIRECTION);

// Ascending sort baseline XY data by X data.
if( OE_NOERROR == nRet )
{
	vector<uint> vn;
	vxBaseline.Sort(SORT_ASCENDING, true, vn);
	vyBaseline.Reorder(vn);
}

Removing a Baseline

If the x coordinate of a baseline is the same as that of the peak curve, you can directly subtract, otherwise you need do interpolation before removing the baseline. The following code shows how to do interpolation and then remove a baseline. Assume the current worksheet has 4 columns in which to put peak XY data and baseline XY data.

Worksheet wks = Project.ActiveLayer();

Column colPeakX(wks, 0), colPeakY(wks, 1);
Column colBaseLineX(wks, 2), colBaseLineY(wks, 3);

// Get peak XY data. 
// Get Y data by reference since want to subtract baseline on it below.
vector vPeakX = colPeakX.GetDataObject();
vector& vPeakY = colPeakY.GetDataObject();

// Get base line data
vector vBaselineX = colBaseLineX.GetDataObject();
vector vBaselineY = colBaseLineY.GetDataObject();	

if( vPeakX.GetSize() != vPeakY.GetSize() 
	|| vPeakX.GetSize() == 0 
	|| vBaselineX.GetSize() == 0
)
	return;

// do interpolation on baseline data to keep x coordinate same as peak data.
vector vyBaseTemp(vPeakX.GetSize());
if(OE_NOERROR != ocmath_interpolate(vPeakX, vyBaseTemp, vPeakX.GetSize(), 
	vBaselineX, vBaselineY, vBaselineX.GetSize(), INTERP_TYPE_LINEAR)) 
{
	return;
}

// subtract base line
vPeakY -= vyBaseTemp;

Finding Peaks

The ocmath_find_peaks_* function is used to find peaks by multiple methods.

The following example shows how to find a local maximum point in a local scope selected by nLocalPts. For a current point marked by nIndex, the scope is [nIndex-nLocalPts, nIndex+nLocalPts].

// Allocate memory for output vectors
UINT nDataSize = vxData.GetSize();
vector vxPeaks(nDataSize), vyPeaks(nDataSize);
vector<int> vnIndices(nDataSize);

// nDataSize, on input, the size of vxData, vyData; 
// on output, return number of peaks
int nLocalPts = 10;
int nRet = ocmath_find_peaks_by_local_maximum( &nDataSize, vxData, vyData, 
	vxPeaks, vyPeaks, vnIndices, 
	POSITIVE_DIRECTION | NEGATIVE_DIRECTION, nLocalPts);

if(OE_NOERROR == nRet) 
{
	printf("Peak Num=%d\n", nDataSize);
	vxPeaks.SetSize(nDataSize);
	vyPeaks.SetSize(nDataSize);
}

Origin C supports two functions: ocmath_test_peaks_by_height and ocmath_test_peaks_by_number, to verify peaks by specified height and peak number, respectively.

The following is an example showing how to verify peaks by minimum peak height.

// Get minimum and maximum from source Y data
double dMin, dMax;
vyData.GetMinMax(dMin, dMax); 

// Get the bigger value from the highest point or the lowest point.
// And multiply 20% to get the peak minimum height.
double dTotalHeight = max(abs(dMax), abs(dMin));
double dPeakMinHeight = dTotalHeight * 20 / 100;

// Verify peaks by specified minimum height
nRet = ocmath_test_peaks_by_height(&nDataSize, vxPeaks, vyPeaks, vnIndices, 
	dPeakMinHeight);	

printf("Peak Num = %d\n", nDataSize);
for(int ii=0; ii<nDataSize; ii++)
{
	printf("Peak %d: (%f,%f)\n", ii+1, vxPeaks[ii], vyPeaks[ii]);
}

Integrating and Fitting Peaks

Integrate Peak

The ocmath_integrate function is used to integrate to find the area under a curve.

The following example shows how to perform integration on the sub curve of one peak.

int i1 = 51, i2 = 134; // From/to index to set the sub range of one peak
IntegrationResult IntResult; // Output, integration result
vector vIntegral(i2+1); // Output, integral data

// Integrate and output result
if( OE_NOERROR == ocmath_integrate(vx, vy, i1, i2, &IntResult, vIntegral, 
MATHEMATICAL_AREA, NULL, false, SEARCH_FROM_PEAK) )
{
	printf("Peak 1: Peak Index = %d, Area = %g, FWHM = %g, Center = %g, 
		Height = %g\n", IntResult.iPeak, IntResult.Area, IntResult.dxPeak, 
		IntResult.xPeak, IntResult.yPeak);
}

Fitting Peak

The Origin C NLFitSession class supports a method to fit peaks with a different fitting function.