/*------------------------------------------------------------------------------*
 * File Name: curve_utils.h													    *
 * Creation: Sandy 12/14/05														*
 * Purpose: support utility functions for all curve data set               		*
 * Copyright (c) OriginLab Corp.2005											*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 * Cloud 04/04/2007 ADD_FIND_PEAKS_BY_NUMBER									*
 * Cloud 04/10/2007 PROCESS_THE_NEGATIVE_PEAK									*
 * Cloud 04/14/2007 REORGANIZE_FUNCTIONS										*
 *	Hong 11/23/07 v8.0753 CLEAN_CENTRALIZE_CODE_AVOID_DATAPLOT_DEPENDENCE		*
 *	CPY 12/8/2007 QA80-10788 FIND_FLAT_REGIONS_IN_CURVE							*
 *	Cloud 12/11/07 QA80-10788 MOVE_TO_OCMATH									*
 *	Hong 12/20/07 v8.0773d IMPROVE_FILTER_PEAK_ALLOW_SPECIFY_FILTER_VALUE		*
 *	Arvin 03/13/08 REPLICA_AUTO_INIT_PARAMS_FOR_SURFACE_FIT						*
 *	Folger 04/18/08 QA80-11441 CENTRALIZE_CODE_OF_LOCAL_MAXIMUN_METHOD			*
 *	Sim 06-06-2008 SEPARATE_AUTO_FIND_BASELINE_POINTS							*
 *	Jack QA-12334 10/09/2008 ADD_ONE_PEAK_MATRIX_DATA_INITILIZE_CODE			*
 *	Jasmine 08/28/09 CENTRALIZE_FIND_PEAK_METHOD_COMBO							*
 *	Kyle 03/11/2010 PICK_PEAK_ROI_TOOL_SHARES_UTILS_FUNCTION_WITH_PA			*
 *	Folger 03/18/10 QA81-15209 IMPROVE_PA_FIND_PEAKS_FOR_NONE_BASELINE			*
 *	Folger 09/27/2010 CODE_CLEANUP_ABOUT_FINDING_PEAKS							*
 *------------------------------------------------------------------------------*/

#ifndef _CURVE_UTILS_H
#define _CURVE_UTILS_H

#include <xfGraph_utils.h>

//
 //enum
//{
	//POSITIVE_DIRECTION = 1,
	//NEGATIVE_DIRECTION,
  	//BOTH_DIRECTION,
//};
//
//define mode for check_linear()
#define CHECK_LINEAR_NORMAL 	1.0
#define CHECK_LINEAR_FINE   	0.0
#define CHECK_LINEAR_OTHERS   	2.0

#define     NUM_SMOOTH_POINT_FOR_NOISE   11
#define     NUM_SMOOTH_POINT_FOR_PEAKS   1

#define 	MAX_SMOOTH_POINTS_OF_BASELINE 25




//Comments last updated by Sandy on 12/15/05
/**$
		Create a Baseline for Masking Peaks vectors depending on original data
	Paramaters:
		vbxi = [input] X Data of initial baseline or original data.
		vbyi = [input] Y Data of initial baseline or original data.
		vbxo = [output] X Data of estimate baseline
		vbyo = [output] Y Data of estimate baseline

	Example1:
		void create_baseline_by_masking_peaks_ex1(vector& vx, vector& vy, int lEndSize)
		{
			vector vx1, vy1;
			int nSize = vx.GetSize();
			if(nSize < lEndSize)
				return;
			
			vx.GetSubVector(vx1, lEndSize, nSize - lEndSize -1);
			vy.GetSubVector(vy1, lEndSize, nSize - lEndSize -1);

			if ( !create_baseline_by_masking_peaks( vx1, vy1,  vx, vy )	) 
			{
			   return;
			}
		}
	Return:
		Return true if succeed.
*/
//2006-4-5 add by Sandy REPLACE_CREATE_BASELINE_MASK
bool create_baseline_by_masking_peaks(const vector& vbxi, const vector& vbyi, vector& vbxo, vector& vbyo);
#define SMOOTH_LEVEL 25
//bool create_baseline_mask(const vector& vbxi, const vector& vbyi, vector& vbxo, vector& vbyo);


//Comments last updated by Sandy on 12/15/05
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:create_baseline_by_positive_peak_mask_(global_function)
*/
bool create_baseline_by_positive_peak_mask(const vector& vxi, const vector& vyi, vector& vbxo, vector& vbyo);

//Commetnts last updated by Sandy on 12/27/05
/**
	    find peak with subtract the baseline and check height and width
	Paramaters:
	Example1:
		void find_peaks_from_baseline_ex1()
		{

		}
		

	Return:
		Return true if succeed.
*/
//bool find_peaks_from_baseline_1st_derivative(vector& vx, vector& vy, const vector &vbx, const vector& vby, vector<int>& vnIndices,
//            vector<int>& vFeetInd, double dMinHeight, double dMaxWidth, double dMinWidth, int nDir = 0);
//bool find_peaks_from_baseline_1st_derivative(vector& vx, vector& vy, const vector& vbx, const vector& vby, 
                                       //int nDir, vector<int>& vnIndices, vector& vxPeaks, vector& vyPeaks);
///Sandy 2006-6-23 replay core math function with ocmath
//bool find_peaks_from_baseline_1st_derivative(vector& vx, vector& vy, const vector& vbx, const vector& vby, int nDir,
			 //vector<int>& vnIndices, vector& vxPeaks, vector& vyPeaks, int* nSize, bool bSmoothMode = true);

                                       
                                       

//Sandy 2005-12-26 MOVE_FROM_PFM_UTTILES
//Commetnts last updated by Frank on 1/06/05
/**	>Analysis>Spectral Analysis
		Algorithm for finding baseline points in a dataset

		Examine second derivative of the data and accept values that are close to zero as baseline points.
		
		The following is a step by step process of the algorithm described above:
		1. Perform 3-pt adjacent averaging smooth on the input data
		2. Take the second derivative of the data
		3. For all points in the second derivative with absolute value above a user-specified Percentile value, 
		    change the corresponding points in original dataset to missing value
		4. For all points that still remain in the original dataset, remove those that do not have an immediate neighbor on either side
		5. Record the indices of all points that remain in the dataset, that are not missing values. These are now the indices of the baseline points for the dataset
	Parameters:
		crvData =[input] the input data curve to find baseline points
		vBsln =[output] the vector that will contain the index values for the baseline points
		dPercentile =[input] input value that will a percentile from 0 to 100 of the absolute value of the second derivative of the data.
	Example1:
		//For this sample to run, column A, B, C should exist.  The dataset to operate on
		//should be in columns A and B.  The index values for the baseline points will be loaded into
		//column C.  
		//For example, import "Positive & Negative Peaks.DAT" from the /Samples/Data folder
		//and copy the data into the the current worksheet worksheet.  Add a column C for the baseline index values.
		void curve_find_baseline_ex1(double dPercentile)
		{
			// call lloc to find baseline points
			Worksheet wks = Project.ActiveLayer();
			if(wks)
			{
				Curve crvData(wks, 0, 1);
				Dataset dsBase(wks, 2); 
				int iRet = curve_find_baseline(crvData, dsBase, dPercentile);
				printf("%d baseline points were found.\n", iRet);
			}
		}
	Return:
		-1  Problem 3-pt adjacent averaging smooth
		-2  Problem taking derivative of data
*/
//int curve_find_baseline(curvebase& crvData, vector& vBsln, double dPercentile);


//Sandy 2005-12-26 MERGE_FIND_PEAKS_WITH_1ST_DERIVATIVE_FUNCTION_TO_ONE_FUNCTION
////Commetnts last updated by Frank on 08/11/05
///**	>Analysis>Spectral Analysis
		//Algorithm for finding peaks in a dataset
//
		//Examine all points of the 1st deriv and look for zero crossings.  If there is a zero crossing
		//in the derivative and the absolute value of the original data is above a theshold, then that
		//corresponds to a peak.
//
		//The following is a step by step process of the algorithm described above:
		//1. Perform 3-pt adjacent averaging smooth on the input data
		//2. Take the first derivative of the data
		//3. Save all points of the 1st deriv that have a zero crossings
		//4. Remove zero crossing points where the absolute value of the original data is within the Threshold value
		//5. Save the index values where the zero crossing is from negative to positive as a negative peak
		//6. Save the index values where the zero crossing is from positive to negative as a positive peak
	//Parameters:
		//crvData =[input] the data curve that we will be using
		//vPks =[input] the index of the curve that the peak points
		//dThresh =[input] Compute cut-off threshold value, by scaling it also with X step value and
		//the spread in Y.  Scaling with X step and Y spread makes the threshold cut similar
		//over various datasets.
		//iDirection =[input] 1: only positive peaks; = -1: only negative peaks; =0: both pos and neg peaks
	//Example1:
		////For this sample to run, column A, B, C should exist.  The peak data
		////should be in columns A and B.  The index values for the peaks will be loaded into
		////column C.  
		////For example, import "Positive & Negative Peaks.DAT" from the /Samples/Data folder
		////and copy the data into the the current worksheet worksheet.  Add a column C for the index values.
		//void curve_find_peaks_ex1(double dThresh, int iDirection = 0)
		//{
			//// call lloc to find peak points
			//Worksheet wks = Project.ActiveLayer();
			//if(wks)
			//{
			//Curve crvData(wks, 0, 1);
			//Dataset dsPeaks(wks, 2); 
			//int iRet = curve_find_peaks(crvData, dsPeaks, dThresh, iDirection);
			//printf("%d peaks were found.\n", iRet);
			//}
		//}
	//Return:
		//-1  Problem with 3-pt adjacent averaging smooth
		//-2  Problem taking derivative of data
//*/
//int curve_find_peaks(const curvebase& crvData, vector& vPks, double dThresh, int iDirection = 1);
//
/////Forest 7/30/04 QA70-6077 PEAK_FIRST_DERIVATIVE_METHOD
////Commetnts last updated by Frank on 1/06/05
///**	>Analysis>Spectral Analysis
		//Algorithm for finding peaks in a dataset
//
		//Examine all points of the 1st deriv and look for zero crossings.  If there is a zero crossing
		//in the derivative and the absolute value of the original data is above a theshold, then that
		//corresponds to a peak.
//
		//The following is a step by step process of the algorithm described above:
		//1. Perform adjacent averaging smooth on the input data, or perform no smoothing
		//2. Take the first derivative of the data
		//3. Save all points of the 1st deriv that have a zero crossings
		//4. Remove zero crossing points where the absolute value of the original data is within the Threshold value
		//5. Save the index values where the zero crossing is from positive to negative as a positive peak
		//6. Save the index values where the zero crossing is from negative to positive as a negative peak
	//Parameters:
		//vxData =[input] the input x data of curve to find peaks
		//vyData =[input] the input y data of curve to find peaks
		//vxPeaks =[output] the x data value of peaks
		//vyPeaks =[output] the y data value of peaks
		//dThresh =[input] Compute cut-off threshold value, by scaling it also with the spread in Y
				  //to make the threshold cut similar	over various datasets.
		//iDirection =[input] 1: only positive peaks; = -1: only negative peaks; =0: both pos and neg peaks
		//nSmoothPts =[input] 3: number of points to perform the averaging smooth, 0 = no smoothing
	//Example1:
		////For this sample to run, Origin workspace should have worksheet and have 4 columns A, B, C, D.  The dataset to operate on
		////should be in columns A and B.  The values for the peak points will be loaded into
		////column C and D  
		////For example, import "Positive & Negative Peaks.DAT" from the /Samples/Data folder
		////and copy the data in worksheet and make it active.  Add column C and D for the peak points.
		//void find_peaks_1st_derivative_ex1(double dThresh, int iDirection = 0)
		//{
			//// call lloc to find peak points
			//Worksheet	wks = Project.ActiveLayer();
			//Dataset dsDataX(wks,0);
			//Dataset dsDataY(wks,1);
			//Dataset dsPeakX(wks,2);
			//Dataset dsPeakY(wks,3);
			//int iRet = find_peaks_1st_derivative(dsDataX, dsDataY, dsPeakX, dsPeakY, dThresh, iDirection);
			//printf("%d peaks were found.\n", iRet);
		//}
	//Return:
		//the number of peaks found if success, otherwise returns error code
		//-1  Problem with adjacent averaging smooth
		//-2  Problem taking derivative of data
//*/
//int find_peaks_1st_derivative(vector& vxData, vector& vyData, vector& vxPeaks, vector& vyPeaks, double dThresh, int iDirection = 0, int nSmoothPts = 3);
//end MERGE_FIND_PEAKS_WITH_1ST_DERIVATIVE_FUNCTION_TO_ONE_FUNCTION

//Commetnts last updated by Frank on 1/06/05
/**	>Analysis>Spectral Analysis
		Algorithm for finding base markers in a dataset

		For all peaks found earlier using Peak Finding LLOC, for each pair
		of points to the left and right of the peak, if there is a change
		in the sign of the 1st derivative, This change then marks the base
		for that peak.

		The following is a step by step process of the algorithm described above:
		1. Take the first derivative of the data
		2. Save all points of the 1st deriv that have a zero crossings
		3. Loop through all peaks, for each pair of points to the left and right
		   of the peak, we look for a change in the sign of the 1st derivative,
		   which is opposite in sense to the change that corresponded to the peak
		   finding algorithm. This change then marks the base for that peak.
		
	Parameters:
		vxData =[input] the input x data of curve to find peaks
		vyData =[input] the input y data of curve to find peaks
		vxPeaks =[output] the x data value of peaks
		vyPeaks =[output] the y data value of peaks
		vxBaseMarkers =[output] the result x data of basemarkers
		vyBaseMarkers =[output] the result y data of basemarkers
	Example1:
		//For this sample to run, Origin workspace should have worksheet and have 6 columns A, B, C, D, E, F.
		//The dataset to operate on should be in columns A and B.
		//The values for the peak points will be loaded into column C and D  
		//The values for the base markers will be loaded into column E and F
		//For example, import "Positive & Negative Peaks.DAT" from the /Samples/Data folder
		//and copy the data in worksheet and make it active.  Add column C, D, E and F for the peak points and base markers.
		void find_basemarkers_1st_derivative_ex1(double dThresh, int iDirection = 0)
		{
			// call lloc to find peak points
			Worksheet	wks = Project.ActiveLayer();
			Dataset dsDataX(wks,0);
			Dataset dsDataY(wks,1);
			Dataset dsPeakX(wks,2);
			Dataset dsPeakY(wks,3);
			Dataset dsBaseMarkerX(wks,4);
			Dataset dsBaseMarkerY(wks,5);
			int iRet = find_peaks_1st_derivative(dsDataX, dsDataY, dsPeakX, dsPeakY, dThresh, iDirection);
			printf("%d peaks were found.\n", iRet);
			find_basemarkers_1st_derivative(dsDataX, dsDataY, dsPeakX, dsPeakY, dsBaseMarkerX, dsBaseMarkerY);
		}
	Return:
		Return 0 if success, otherwise returns error code
		-1  Problem taking derivative of data
*/


//int find_basemarkers_1st_derivative(vector& vxData, vector& vyData, vector& vxPeaks, vector& vyPeaks, vector& vxBaseMarkers, vector& vyBaseMarkers);
///End PEAK_FIRST_DERIVATIVE_METHOD

///End MOVED_PEAK_AND_BASLINE_FUNCS_TO_PFM_UTILS

/**
	Remarks:
	Keywords:
	Example1:
		//This is a self-contained example for peak finding. The example creates its
		//	own data with randomly generated peak centers. Then the Origin C routine 
		//  for peak searching is called. Finally, to illustrate the result, the centers
		//  of peaks found are draw together with the input data in a graph.
		
		//Sandy 2006-1-13  REWRITE_THE_EXAMPLE_CODE
		void find_peaks_1st_derivative_ex1()
		{
			Worksheet wks = Project.ActiveLayer();
			if(!wks)
			    return;
			
			Dataset dsX(wks, 0);
			Dataset dsY(wks, 1);
			Dataset dsOut; 
			dsOut.Attach(wks, 2);
			
			vector vx = dsX;
			vector vy = dsY;
			
			GraphPage gp;
			gp.Create("Line");
			GraphLayer gl = gp.Layers(0);
			gl.AddPlot(wks, IDM_PLOT_LINE);
			gl.Rescale();
			
			vector vxPeaks, vyPeaks;
			vector<int>  vnIndices;
			
			find_peaks_1st_derivative(vx, vy, vxPeaks, vyPeaks,vnIndices, 0, 11);	 
			
			Axis ay = gl.YAxis;
			
			Tree tryScale;
			tryScale = ay.Scale;
		
			for (int k = 0; k < vxPeaks.GetSize(); k++)
			{
				int n1st = wks.AddCol();
				int n2nd = wks.AddCol();
				Dataset ds1(wks, n1st), ds2(wks, n2nd);
				ds1.SetSize(2);
				ds2.SetSize(2);
				
				ds1[0] = vxPeaks[k];
				ds1[1] = vxPeaks[k];
				ds2[0] = tryScale.From.dVal;
				ds2[1] = tryScale.To.dVal;
			
				Curve crv(wks, n1st, n2nd);
				int nPlot = gl.AddPlot(crv, IDM_PLOT_LINE);
				gl.DataPlots(nPlot).SetColor(2);
			}
		}
	Parameters:
		vxData = [input]
		vyData = [input]
		vxPeaks = [output]
		vyPeaks = [output]
		nDir = [input]  
		       BOTH_DIRECTION: find peaks in both direction
		       NEGATIVE_DIRECTION: only find peaks in negative direction
		       POSITIVE_DIRECTION: only find peaks in positive direction
		numPeaks = [input]
		nPtsSmooth = [input]
	Return:
	SeeAlso: find_peaks_2nd_derivative
 */ 


//Sandy 2005-12-26 CHANGE_FUNCTION_NAME_AFTER_MERGE_RELATIVE_FUNCTIONS
//bool find_peaks_1st_derivative2(vector& vxData, vector& vyData, vector& vxPeaks, vector& vyPeaks, int nDir = PEAKS_POSITIVE, int nPtsSmooth = 11);
bool find_peaks_1st_derivative(const vector& vxData, const vector& vyData, 
							   vector& vxPeaks, vector& vyPeaks,
							   vector<int>& vnIndices, int nDir = POSITIVE_DIRECTION, int nPtsSmooth = 11);


/**#
	Remarks:
	Keywords:
	Example1:
		void test_peaks_by_number_ex1
		{
		
		}
	Parameters:
		vxPeaks = [modify]
		vyPeaks = [modify]
		numPeaks = [input]
	Return:
	SeeAlso:
 */ 
bool test_peaks_by_number(vector& vxPeaks, vector& vyPeaks,vector<int>& vnIndices, int numPeaks);
//end 2005-12-26 MOVE_FROM_PFM_UTTILES
/**#
	Remarks:
	Keywords:
	Example1:
		void init_baseline_by_connect_ends_ex1
		{
		
		}
	Parameters:
	Return:
	SeeAlso:
 */ 
bool init_baseline_by_connect_ends(const vector& vx, const vector& vy, vector& vbx, vector& vby, int npts);



///Commetnts last updated by Sandy on 2006-2-16 
/**#
	Remarks:
	Keywords:
	Example1:
		void check_linear_ex1
		{
		
		}
	Parameters:
	Return: the linear ending index of vx and vy
	SeeAlso:
 */  


int check_linear(const vector& vx, const vector& vy, double dMaxRatio, double dR = 1.0, 
                       uint nOffset = 0, bool bDir = true);
                       
/**$
		add labels to a data plot
	Parameters:
		dp = [input] data plot to add/remove labels
		vn = [input] indices to label the plot. If this vector is empty, all existing labels will be removed.
		vsLabels = [input] strings to put at each corresponding vn
		nYoffset = [input] vertical offset in font size unit to place the labels
	Example1:
		void add_labels(BOOL bRemoveAll = false)
		{
			GraphLayer gl = Project.ActiveLayer();
			DataPlot dp = gl.DataPlots(0);
			
			vector<int> vn = {0, 10, 30, -1};
			vector<string> vs = {"1st", "2nd", "3rd", "last"};
			if(bRemoveAll)
			{
				vn.SetSize(0);
			}
			curve_labels(dp, vn, vs);
		}
*/                       
bool curve_labels(DataPlot& dp, const vector<int>& vn, const vector<string>& vsLabels, int nYoffset = -80);

bool test_peaks_by_height(vector& vxPeaks, vector& vyPeaks, vector<int>& vnIndices, double dMinHeight);

double get_noise_level(vector& vy);

bool find_feet_of_peaks_by_height_and_width(const vector& vx, const vector& vy, vector<int> vnIndices, 
                      double dFootHeight, double dMaxWidth, double dMinWidth, vector<int>& vFeetInd);
                      
/**#
	Remarks:
	Keywords:
	Example1:
		void find_peaks_partition_ex1
		{
		
		}
	Parameters:
		vxData = [input]
		vyData = [input]
		dxPeak = [input]
		nStart = [output]
		nEnd   = [output]
		nPtsSmooth = [input]
	Return:
	SeeAlso:
 */ 
//bool find_peaks_partition(vector& vxData, vector& vyData, vector& vxSub, vector& vySub, double dxPeak, int nDir = POSITIVE_DIRECTION, int nPtsSmooth = 11);
bool find_peaks_partition(vector& vxData, vector& vyData, double dxPeak, int& nStart, int& nEnd, int nPtsSmooth);

///Sandy 2006-9-6 ready for centralize code
bool subtract_baseline(vector& vx, vector& vy, vector& vbx, vector& vby, bool bResize_vb = false);

///sandy 2006-9-13 move from XF
bool auto_create_baseline(const vector& vx, const vector& vy, vector& vbx, vector& vby, int type, int nSmoothLeftPts);


///Arvin 03/19/07 IMPROVE_CALCULATION_CENTROID_METHOD                      
//bool integrate_curve(const vector& vx, const vector& vy,const vector& vbx, const vector& vby,  int nDir, vector& vIntegrated, ocmath_IntegResult& result);                     
bool integrate_curve(const vector& vx, const vector& vy,const vector& vbx, const vector& vby,  int nDir, vector& vIntegrated, IntegrationResult& result);                     
///end IMPROVE_CALCULATION_CENTROID_METHOD

///Arvin 01/10/06 ADD_CREATING_CURVES_FUNCTIONS_FOR_PALETTE_EDIT_TOOL
//enum{
	//LINE_SEGMENT_CURVE,
	//SPLINE_CURVE,
	//GUASSAMP_CURVE,
	//LOGISTIC_CURVE,
//};

///**
	//Remarks:
		//Create user selected type curve defined by input points.
	//Keywords:
	//Example1:	
		//void create_curve_for_palette_edit_ex1()
		//{
			//GraphLayer gl = Project.ActiveLayer();
			//if (!gl)
			//{
				//return;
			//}
			//
			//DataPlot dp = gl.DataPlots(0);		
			//DataRange dr;
			//vector vx, vy;
	        //if(dp.GetDataRange(dr))
	        //{
	        	//DWORD dwPlotID;
	        	//if(dr.GetData(DRR_GET_DEPENDENT | DRR_NO_FACTORS, 0, &dwPlotID, NULL, &vy, &vx) < 0)
	        	//{
	        		//printf("get_plot_data failed GetData");
	        		//return;
	        	//}
	        //}
			//vector vCurveX, vCurveY;
			//int nPts = 30;
			//int nCurveType = GUASSAMP_CURVE;
			//if(!create_curve_for_palette_edit(vx, vy, vCurveX, vCurveY, nPts, nCurveType))
			//{
				//printf("create_curve_for_palette_edit failed");
				//return;
			//}
			//
			//WorksheetPage wksPage;
			//wksPage.Create();
			//Worksheet wksResult = wksPage.Layers(0);
			//int nXCol, nYCol;
			//nXCol = wksResult.AddCol("X Coordinate");
			//nYCol = wksResult.AddCol("Y Coordinate");
			//wksResult.Columns(nXCol).SetType(OKDATAOBJ_DESIGNATION_X);
			//wksResult.Columns(nYCol).SetType(OKDATAOBJ_DESIGNATION_Y);
			//DataRange drOut;
			//drOut.Add("X", wksResult, 0, nXCol, -1, nXCol);
			//drOut.Add("Y", wksResult, 0, nYCol, -1, nYCol);
			//drOut.SetData(&vCurveY, &vCurveX);
			//XYRange plotRange;
			//plotRange.Add("X", wksResult, 0, nXCol, -1, nXCol);
			//plotRange.Add("Y", wksResult, 0, nYCol, -1, nYCol);
			//gl.AddPlot(plotRange, IDM_PLOT_LINE);
		//}
	//Parameters:
		//vx = [input]
		//vy = [input]
		//vCurveX = [output]
		//vCurveY = [output]
		//nPts = [input]  
		//nCurveType = [input]
	//Return:
	//SeeAlso: find_peaks_2nd_derivative
 //*/ 
///Sandy 2007-2-9 move to XF
//bool create_curve_for_palette_edit(const vector& vx, const vector& vy, vector& vCurveX, vector& vCurveY, int nPts, int nCurveType = LINE_SEGMENT_CURVE);

//bool nlsf_func_curve(const vector& vx, const vector& vy, const string strFuncName, vector& vCurveX, vector& vCurveY);
//
//
//bool nlsf_logistic_curve(const vector& vx, const vector& vy, 
						//const int nPower, const int nCenter,
						//vector& vCurveX, vector& vCurveY);
						
						
///sandy 2007-3-22 add for a new baseline XF and integPeaks.oxf
enum{
	CUR_SUBRANGE_INTERP_TYPE_LINEAR ,
	CUR_SUBRANGE_INTERP_TYPE_BSPLINE ,	
};

enum
{
	PKF_POSITIVE_DIRECTION = 1,
	PKF_NEGATIVE_DIRECTION,
  	PKF_BOTH_DIRECTION,
};

bool fill_subrange_by_interp(vector& vx, vector& vy, double dLeft, double dRight, int nFunction);

bool delete_subrange_of_data(vector& vx, vector& vy, double dLeft, double dRight);

bool fit_poly_baseline(vector& vbx, vector& vby, vector& vxPloy, vector& vyPloy);

/// Cloud 04/14/2007 REORGANIZE_FUNCTIONS
//int find_max_height_peaks(vector& vx, vector& vy, int nNum, vector& vXofPeaks, vector& vYOfPeaks);
int find_max_height_peaks(vector& vx, vector& vy, int nNum, vector& vXofPeaks, vector& vYOfPeaks, vector<int>& vIndexOFPeaks=NULL, int iDir=PKF_BOTH_DIRECTION);
/// End REORGANIZE_FUNCTIONS
///add end 2007-3-22

/// Cloud 04/04/2007 ADD_FIND_PEAKS_BY_NUMBER
/// Cloud 04/10/2007 PROCESS_THE_NEGATIVE_PEAK
//bool find_peaks_by_number(vector& vx, vector& vy, int iPeakNum, vector& vxPeaks, vector& vStart, vector& vEnd, vector<int>& vStartIndice, vector<int>& vEndIndice);
bool find_peaks_by_number_full_auto(vector& vx, vector& vy, int iPeakNum, vector& vxPeaks, vector& vStart=NULL, vector& vEnd=NULL, vector<int>& vStartIndice=NULL, vector<int>& vEndIndice=NULL, int iDir=PKF_BOTH_DIRECTION);
/// End PROCESS_THE_NEGATIVE_PEAK
/// End ADD_FIND_PEAKS_BY_NUMBER				

/// Cloud 04/14/2007 REORGANIZE_FUNCTIONS
bool find_peaks_marker_by_height_and_width(vector& vx, vector& vy, vector<int>& vPeakInd, vector& vStart, vector& vEnd, vector<int>& vStartIndice=NULL, vector<int>& vEndIndice=NULL, int iDir=PKF_BOTH_DIRECTION);
/// REORGANIZE_FUNCTIONS

/// Cloud 05/21/2007 CALC_FEET_HEIGHT_OF_PEAK
double get_feet_height_by_percent_of_total_height(const vector& vy, double percent);
/// End CALC_FEET_HEIGHT_OF_PEAK


///------Sandy 2008-9-9 ADD_LOCAL_BASELINE_VECTOR
///Sandy 2007-5-23 MOVE_FROM_XF
//bool integrate_individual_peak(const vector& vx, const vector& vy, 	double dFromX, double dToX, 
										//IntegrationResult& IntResult, int& nFrom, int& nTo, vector& vIntegrated = NULL);								
//end MOVE_FROM_XF	
bool integrate_individual_peak(const vector& vx, const vector& vy, 	double dFromX, double dToX, 
										IntegrationResult& IntResult, int& nFrom, int& nTo, vector& vIntegrated = NULL,  const vector& vby = NULL);


///Sandy 2007-7-3 MOVE_FROM_BLPWIZ
bool update_smooth_point(TreeNode &tr, vector &vy, string *pstrErrMsg=NULL);

//Sandy 2007-11-5 Add
int interpolate_baseline_base_on_data(vector& vbx, vector& vby, vector& vx, vector& vy, int npts, int nInterpType = INTERP_TYPE_LINEAR);				
///Jasmine 08/28/09 CENTRALIZE_FIND_PEAK_METHOD_COMBO
#define		REGULAR_FIND_PEAK_METHOD		_L("Local Maximum|Window Search|1st Derivative")
#define		PRO_ONLY_FIND_PEAK_METHOD		_L("2nd Derivative (search Hidden peaks)|Residual after 1st Derivative (search Hidden peaks)")
///End CENTRALIZE_FIND_PEAK_METHOD_COMBO

/// Hong 11/23/07 v8.0753 CLEAN_CENTRALIZE_CODE_AVOID_DATAPLOT_DEPENDENCE
enum
{
	FIND_PEAK_LOCAL_MAX = 0,
	FIND_PEAK_WINDOW_SEARCH,
	FIND_PEAK_1ST_DERIVATIVE,
	FIND_PEAK_2ND_DERIVATIVE,
	FIND_PEAK_RESIDUE, /// Hong 11/26/07 v8.0754 CLEAN_CENTRALIZE_CODE_AVOID_DATAPLOT_DEPENDENCE	 
};

///Jasmine 08/28/09 CENTRALIZE_FIND_PEAK_METHOD_COMBO
bool 	is_find_peak_method_available(int nMethod);
string 	get_find_peak_methods();
///End CENTRALIZE_FIND_PEAK_METHOD_COMBO

enum
{
	TEST_PEAK_HEIGHT = 0,
	TEST_PEAK_NUMBER,	
};

int test_peaks(vector& vxPeaks, vector& vyPeaks, vector<int>& vnIndices, int nMothed, double dTestValue);

/// Hong 12/20/07 v8.0773d IMPROVE_FILTER_PEAK_ALLOW_SPECIFY_FILTER_VALUE
//int find_peaks(vector& vxData, vector& vyData, vector& vxPeaks, vector& vyPeaks, vector<int>& vnIndices, int nFindMathod,
//		double& dWidth, double& dHieght, int nPtsSmooth, int nDir = BOTH_DIRECTION, int npts = 0, bool bPercent = false, int nTestMathod = -1);

///---Sandy 2008-11-20 APPLY_NEW_OCMATH_FUNCTION_PROTOTYPE_WITH_SG_DERIV
//int find_peaks(vector& vxData, vector& vyData, vector& vxPeaks, vector& vyPeaks, vector<int>& vnIndices, int nFindMathod,
//		double& dWidth, double& dHieght, int nPtsSmooth, int nDir = BOTH_DIRECTION, int npts = 0, bool bPercent = false, int nTestMathod = -1, const double* pdFilterValue = NULL);
enum{
	DERIV_SMOOTH_NONE,
	DERIV_SMOOTH_FFT,
	DERIV_SMOOTH_ADJ,
	DERIV_SMOOTH_SG,
	DERIV_SMOOTH_QSG,
};
int find_peaks(vector& vxData, vector& vyData, vector& vxPeaks, vector& vyPeaks, vector<int>& vnIndices, int nFindMathod,
		double& dWidth, double& dHieght, int nPtsSmooth, int nDir = BOTH_DIRECTION, int npts = 0, bool bPercent = false, int nTestMathod = -1, const double* pdFilterValue = NULL,
		 int nSmoothDerivativeMethod = 0, vector& v2ndDeriv = NULL, int nSGPtsSmooth = 11, double dFFTCutOff = 0.2,  int nPolyOrder = 2);
//---end APPLY_NEW_OCMATH_FUNCTION_PROTOTYPE_WITH_SG_DERIV
/// end IMPROVE_FILTER_PEAK_ALLOW_SPECIFY_FILTER_VALUE
/// end CLEAN_CENTRALIZE_CODE_AVOID_DATAPLOT_DEPENDENCE

///------ Folger 03/18/10 QA81-15209 IMPROVE_PA_FIND_PEAKS_FOR_NONE_BASELINE
int find_peaks_without_baseline(vector& vx, vector& vy, vector& vxPeaks, vector& vyPeaks, vector<int>& vnIndices, int nFindMathod,
					double& dWidth, double& dHieght, int nPtsSmooth, int nDir = BOTH_DIRECTION, int npts = 0, bool bPercent = false, int nTestMathod = -1, const double* pdFilterValue = NULL,
					int nSmoothDerivativeMethod = 0, vector& v2ndDeriv = NULL, int nSGPtsSmooth = 11, double dFFTCutOff = 0.2,  int nPolyOrder = 2);
///------ End IMPROVE_PA_FIND_PEAKS_FOR_NONE_BASELINE

//----- CPY 12/8/2007 QA80-10788 FIND_FLAT_REGIONS_IN_CURVE
/// Cloud 12/11/07 QA80-10788 MOVE_TO_OCMATH
/*
typedef struct tagLRresults
{
	uint	i1;
	uint	i2;
	double	a;
	double	b;
	double	aErr;
	double	bErr;
	double	Rvalue;			// R Value
	double	AdjRSq;			// Adjusted residuel sum of squares
} LRresults;

/// End MOVE_TO_OCMATH
int fit_linear_multi_regions(const vector& vxData, const vector& vyData, const vector<int>& vBegs, const vector<int>& vEnds, LRresults* pResults);
int find_base_regions(const vector& vxData, const vector& vyData, int nMinBasePts, vector<int>& vBegs, vector<int>& vEnds, double dTol = 1.0, double dMaxSearchSize = 0.4, bool bUseSlope=false);
*/
//-----

bool match_peaks_centers_by_index(const vector& vxi,const vector& vyi, const int nPeaksNum, const vector<int>& vPeaksInd, vector& vxPeaks,vector& vyPeaks );

///Sandy 2007-6-12 add markers index output
///// Cloud 05/17/2007 ADD_DEFAULT_VALUE_WHEN_NOT_FIND_PEAK_FEET
//void get_peaks_data_from_parent_data(vector& vyi, vector& vxi, int nPeakNum, vector<int>& vPeaksInd, vector& vxPeaks, vector&  vyPeaks,
////					 vector<int>& vFeetInd, vector& vxLFeet, vector& vyLFeet, vector& vxRFeet, vector& vyRFeet);
					 //vector<int>& vFeetInd, vector& vxLFeet, vector& vyLFeet, vector& vxRFeet, vector& vyRFeet, const double* pLFeet=NULL, const double* pRFeet=NULL);
///// End ADD_DEFAULT_VALUE_WHEN_NOT_FIND_PEAK_FEET
void get_peaks_info_from_index_within_maxwidth(vector& vyi, vector& vxi, int nPeakNum, vector<int>& vPeaksInd, vector& vxPeaks, vector&  vyPeaks,
					 vector<int>& vFeetInd, vector& vxLFeet, vector& vyLFeet, vector& vxRFeet, vector& vyRFeet, const double* pLFeet=NULL, const double* pRFeet=NULL);


int compute_peaks_markers_all_infomation(const vector& vxOrigin, const vector& vyOrigin, 
	const vector& vxData, const vector& vyData, vector<int>& vnPeaksIndices, vector& vxPeaks, vector& vyPeaks, 
	double dMaxFullWidth, vector& vxLFeet, vector& vyLFeet,vector& vxRFeet, vector& vyRFeet, vector<int>& vMarkersInd);
	

//Sandy 2008-4-8 Remove from OC
///Add by Sandy 2008-2-14
///sort points firstly by derivative absolute value, secondly by the absolute difference with average height,
///the processing will help to find out which points are more like baseline points.
//bool sort_points_by_base_derivative(const vector& vx, const vector& vy, vector& vbx, vector& vby);



///Sandy Move from XF 2008-3-12
void	snap_points_to_source_data(const vector& vxSource, const vector& vySource, vector& vx, vector& vy);


///Arvin 03/11/08 REPLICA_AUTO_INIT_PARAMS_FOR_SURFACE_FIT

//move to anaysis_utils.h
/*
typedef struct tagFindPeakCtrlInfo
{
	int 	_id(IDE_REPLICA_PARAM_INIT_SMOOTH_PTS) 		nSmoothPts;
	int 	_id(IDE_REPLICA_PARAM_INIT_DIRECTION)		nDirection;
	int 	_id(IDE_REPLICA_PARAM_INIT_METHOD)			nFindPeakMethod;
	int 	_id(IDE_REPLICA_PARAM_INIT_LOCAL_POINTS)	nLocalPts;
	bool 	_id(IDE_REPLICA_PARAM_INIT_SIZE_OPTIONS)	bPercent;
	double 	_id(IDE_REPLICA_PARAM_INIT_WIN_HEIGHT)		dWinWidth;
	double 	_id(IDE_REPLICA_PARAM_INIT_WIN_WIDTH)		dWinHeight;
	int		_id(IDE_REPLICA_PARAM_INIT_PEAK_FILTER)		nFilter;
	double 	_id(IDE_REPLICA_PARAM_INIT_FILTER_VALUE)	dFilterValue;
}FindPeakCtrlInfo;
*/

//------ Folger 03/13/08 COMMENT_CODE_THAT_LEADS_TO_LINKING_ERROR
//this function makes linking error in NLFitSession, just comment out here

//------ Folger 04/18/08 QA80-11441 CENTRALIZE_CODE_OF_LOCAL_MAXIMUN_METHOD
//int smooth_points_calculation_for_finding_peak(const vector& vDependent);
int smooth_points_calculation_for_finding_peak(const vector& vDependent, int nMethod);
//------

int init_1d_peak_parameters_for_replica_fitting(const vector& vX, const vector& vY, int nNumNeededPeaks, vector& vXCenter, vector& vYCenter, vector& vXWidth, const FindPeakCtrlInfo* pCtrlInfo);
int init_2d_peak_parameters_for_replica_fitting(const vector& vxGrid, const vector& vyGrid, const vector& vzGrid, int nNumNeededPeaks, vector& vXCenter, vector& vYCenter, vector& vZCenter, vector& vXWidth, vector& vYWidth, const FindPeakCtrlInfo* pCtrlInfo);
///end REPLICA_AUTO_INIT_PARAMS_FOR_SURFACE_FIT

//------ End COMMENT_CODE_THAT_LEADS_TO_LINKING_ERROR

///---Sim 06-06-2008 SEPARATE_AUTO_FIND_BASELINE_POINTS
// move from pa_basemode.oxf
#define BL_AUTO_FIND_THRESHOLD 0.05
bool bl_auto_find_baseline_points(vector& vx, vector& vy, vector& vebx, vector& veby, int& npts, double dThreshold = BL_AUTO_FIND_THRESHOLD);
///---END SEPARATE_AUTO_FIND_BASELINE_POINTS

///Sandy 2008-9-11 add local baseline 
enum{
	LOCAL_BASELINE_LINE,
	LOCAL_BASELINE_SPLINE,
};
int get_local_baseline_by_interp(const vector& vx, const vector& vy, vector& vxLocalBaseline, vector& vyLocalBaseline, double dLeft, double dRight, int nType, int& nLeft = NULL, int& nRight = NULL);

int get_sub_range_from_xy(vector& vx, vector& vy, double dBeginX, double dEndX, int& nBeginX, int& nEndX);

/// Jack QA-12334 10/09/2008 ADD_ONE_PEAK_MATRIX_DATA_INITILIZE_CODE
// for usage in one peak matrix data initial code
bool get_xz_yz_curves_at_max_min_z_peak_from_matrix_data( Curve& x_curve , Curve& y_curve,  const Matrix& mzData);
/// End ADD_ONE_PEAK_MATRIX_DATA_INITILIZE_CODE

///Kyle 03/11/2010 PICK_PEAK_ROI_TOOL_SHARES_UTILS_FUNCTION_WITH_PA

// moved from pa_basemode.oxf
bool auto_find_baseline_anchor_points(vector& vx, vector& vy, vector& vebx, vector& veby, int& npts);

// moved from pa_peaks.oxf
bool compute_peaks_number_by_filter_height(const vector& vx,const vector& vy, double dHeightThres, int& iPeakNum);
///End PICK_PEAK_ROI_TOOL_SHARES_UTILS_FUNCTION_WITH_PA

///------ Folger 09/27/2010 CODE_CLEANUP_ABOUT_FINDING_PEAKS
BOOL	check_sort_data_for_find_peaks(vector& vY, vector& vX);
///------ End CODE_CLEANUP_ABOUT_FINDING_PEAKS

/// Hong 0227/08 v8.0803 MISSING_IF_DEFINE_MATCH
#endif // _CURVE_UTILS_H
/// end MISSING_IF_DEFINE_MATCH
