/*------------------------------------------------------------------------------*
 * File Name:fft_utils.h 														*
 * Creation: ER 5/15/03															*
 * Purpose: Origin's internal FFT analysis routines								*
 * Copyright (c) Originlab Corp.	2003										*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	Cheney 2006-7-19 AUTO_COMPUTE_SAMPLING_INTERVAL_FROM_INPUTDATA				*
 *	Cheney 2006-7-19 AUTO_COMPUTE_PARAMS_VALUE									*
 *	Cheney 2006-8-4 WINDOW_FILTER												*
 *  Justin 2007-3-22 v8.0587 CHECK_USER_INPUTED_INTERVAL                        *
 *  Justin 2007-3-23 v8.0588 MOVE_BACK_FFTUTILIS_BECAUSE_COMPILE_ERROR			*
 *  Justin 2007-04-04 MODIFY FUCNTION CATEGORY									*
 *	Fisher 2008-9-13	GRAPH_OBJ_CURVE_TOOL									*
 *	Folger 04/17/09 QA80-13429 RECREATE_X_DATA_FOR_NOT_EVEN_SPACE_INPUT_X		*
 *	Fisher	07/29/09 QA80-14034 SET_2DFFT_FREQUENCY_DOMAIN						* 
 *	YuI 10/14/09 QA70-13728-P3 WRONG_AUTOSAMPLING_INTERVAL_IF_OUTPUT_PRODUCES_X_COLUMN*
 *	Kit 10/26/2010 ORG-1227-P3 SUPPORT_OTHER_FFT_TOOL_SHOW_UNITS_ON_REPORT_TABLE*
 *------------------------------------------------------------------------------*/
 
#ifndef _FFT_UTILS_H
#define _FFT_UTILS_H
#include <..\originlab\fft.h>
//#include <ReportTree.h>

enum {     					// STFT Window method
	Rectangle_Win = 0,
	Welch_Win,
	Triangular_Win,
	Bartlett_Win,
	Hanning_Win,
	Hamming_Win,
	Blackman_Win,
	Gaussian_Win,
	Kaiser_Win,
	Parzen_Win,			//Cheney 2006-8-8 ADD_FOR_PARZEN_WINDOW
};

// Comments last updated by Frank on 08/09/05
/**$ >Signal Processing>Fourier Transform
	Remarks:
		handle error codes.
	Parameters:
		nError 		  = [input] error codes. default is UNKNOWN_ERROR(refer to fft.h).
		lpcstrErrInfo = [input]	more detail error informatrion for the individual case. default is NULL
	Return:	
		Returns error codes.
*/
int fft_error_handle(int nError = UNKNOWN_ERROR , LPCSTR lpcstrErrInfo = NULL);

typedef void (*FUNC_POINTER_FFT_AMP)(vector &vx, vector &vy, vector &vfreq, vector &vAmp, int nSize, bool bNormalize = false, bool bOneSide = true); 

/// Fisher 2008-9-13	GRAPH_OBJ_CURVE_TOOL
void fft_amp(vector &vx, vector &vy, vector &vfreq, vector &vAmp, int nSize, bool bNormalize = false, bool bOneSide = true);
/// End GRAPH_OBJ_CURVE_TOOL

///Cheney 2006-7-13 REMOVE_CODE_TO_XF
// Comments last updated by Frank on 08/09/05
/** >Signal Processing>Fourier Transform>FFT
	Remarks:
		Performs circular convolution of signal with response function. 
		The convolution is performed by calling the FFT convolution function.
	Keywords:
		convolution; smooth; shift;
	Example1:
			void convolute_ex1()
			{
				// Create a new worksheet and import data
				WorksheetPage wpg;
				wpg.Create("Origin");
				Worksheet wks = wpg.Layers(0);
				string strFile = GetAppPath(TRUE) + "Samples\\Signal Processing\\Convolution.dat";
				ASCIMP	ascimp;
				wks.GetASCIMP(ascimp);
				if( 0 != wks.ImportASCII(strFile, ascimp) )
				{
					out_str("Failed to import file");
					return;
				}
				
				// Add another column for convolution output
				uint nIndex = wks.AddCol();
				wks.Columns(nIndex).SetLongName("Gaussian Conv");
				// Set up datasets and vectors for function call
				Dataset dsSignal(wks, 1);
				Dataset dsResponse(wks, 2);
				Dataset dsResult(wks, 3);
				vector vecSignal(dsSignal), vecResponse(dsResponse), vecResult;
				vecSignal.Trim();
				vecResponse.Trim();
				
				// Call function to perform convolution
				int iRet = convolute(vecSignal, vecResponse, vecResult);
				if( 0 != iRet )
				{
					printf("Convolution function returned error: %d\n", iRet);
					return;
				}
				// Copy result to dataset
				dsResult = vecResult;
				// 
				// The fourth column in the worksheet will now have the result
				// of the convolution, In this case the input data was a noisy
				// signal and the response was a gaussian peak and so the 
				// convolution results in smoothing the noisy data.
				// 
				//
				// Now change the response column to a simple response function
				vecResponse.SetSize(3);
				vecResponse[0] = 0; vecResponse[1] = 1; vecResponse[2] = 0;
				// Call the convolution function again, but this time set options
				// to not wrap the response function.
				nIndex = wks.AddCol();
				wks.Columns(nIndex).SetLongName("Simple Conv");
				iRet = onvolute(vecSignal, vecResponse, vecResult, TRUE, FALSE);
				if( 0 != iRet )
				{
					printf("Convolution function returned error: %d\n", iRet);
					return;
				}
				Dataset dsResult2(wks, nIndex);
				dsResult2 = vecResult;
				// The fifth column in the worksheet will now have the result of
				// this second convolution call. In this case, the convolution result
				// will just be the signal shifted to the right by one channel				
			}		
	Parameters:
		vecSignal 	= [input] vector with Signal data
		vecResponse = [input] vector with Response data
		vecResult 	= [output]vector to return result of convolution
		bNormalize 	= [input] true: normalize sum of response elements to unity, false: do not normalize
		bWrap 		= [input] true: wrap response so that max value is at 0th element, false: do not wrap
		bCircular 	= [Input] false: if true, do circular convolution; else do linear convolution
	Return:
		Returns OE_NOERROR for no errors, positive number for any FFT-returned error code.
	SeeAlso:
		deconvolute
*/
//int convolute(vector& vecSignal, vector& vecResponse, vector& vecResult, bool bNormalize = true, bool bWrap = true, bool bCircular = false);
///end REMOVE_CODE_TO_XF

///Cheney 2006-7-13 REMOVE_CODE_TO_XF
// Comments last updated by Raine on 25/05/06
/** >Signal Processing>Fourier Transform>FFT
	Remarks:
		Performs correlation of two signals. 
		The correlation is performed by calling FFT functions.
		If specified, the correlation result is normalized to be in the range of +1 to -1.
		The normalization is performed by dividing the result by the following factor:
			square root( (sum of (FFT amplitude of signal 1)^2) * (sum of (FFT amplitude of signal 2)^2) ).
	Example1:
		void correlate_ex1()
		{
				// Create a new worksheet and import data
				WorksheetPage wpg;
				wpg.Create("Origin");
				Worksheet wks = wpg.Layers(0);
				string strFile = GetAppPath(TRUE) + "Samples\\Signal Processing\\Correlation.dat";
				ASCIMP	ascimp;
				wks.GetASCIMP(ascimp);
				if( 0 != wks.ImportASCII(strFile, ascimp) )
				{
					out_str("Failed to import file");
					return;
				}
				
				// Add another column for convolution output
				uint nIndex = wks.AddCol();
				wks.Columns(nIndex).SetLongName("Correlation");
				wks.Columns(nIndex).SetInternalData(FSI_DOUBLE);
				
				// Set up datasets and vectors for function call
				Dataset dsSignal(wks, 0);
				Dataset dsSignal2(wks, 1);
				Dataset dsResult(wks, 2);
				
				int nSize = dsSignal.GetSize();
				vector vecSignal(dsSignal), vecSignal2(dsSignal2), vecResult(dsResult);
				vecSignal.Trim();
				vecSignal2.Trim();
				
				// Call function to perform correlation
				int iRet = correlate(vecSignal, vecSignal2, vecResult);
			
				if( 0 != iRet )
				{
					printf("Correlate function returned error: %d\n", iRet);
					return;
				}
				
				// Copy result to dataset
				dsResult = vecResult;		
		}
	Parameters:
		vecSignal1 	   = [Input] vector with Signal1 data
		vecSignal2 	   = [Input] vector with Signal2 data
		vecCorrelation = [Output]vector with correlation result
		bNormalize 	   = [Input] normalize corelation result to +/-1 range if true. default is true.
		bCircular 	   = [Input] perform circular correlation if true or else linear correlation.
								 default is true.
	Return:
		Returns 0 for no errors, positive number for any FFT-related error code.
*/
//int correlate(vector& vecSignal1, vector& vecSignal2, vector& vecCorrelation, bool bNormalize = true, bool bCircular = true);
///end REMOVE_CODE_TO_XF

///Cheney 2006-7-13 REMOVE_CODE_TO_XF
// Comments last updated by Frank on 08/09/05
/** >Signal Processing>Fourier Transform>FFT
	Remarks:
		Performs deconvolution of signal with response function. 
		The deconvolution is performed by calling FFT functions.
	Keywords:
		deconvolution;
	Example1:
			void deconvolute_ex1()
			{
				// Create a new worksheet and import data
				WorksheetPage wpg;
				wpg.Create("Origin");
				Worksheet wks = wpg.Layers(0);
				string strFile = GetAppPath(TRUE) + "Samples\\Signal Processing\\Deconvolution.dat";
				ASCIMP	ascimp;
				wks.GetASCIMP(ascimp);
				if( 0 != wks.ImportASCII(strFile, ascimp) )
				{
					out_str("Failed to import file");
					return;
				}
				
				// Add another column for the deconvolution output
				uint nIndex = wks.AddCol();
				wks.Columns(nIndex).SetLongName("Deconvolution Result");
				// Set up datasets and vectors for function call
				Dataset dsConvolutedSignal(wks, 1);
				Dataset dsInstrumentResponse(wks, 2);
				Dataset dsDeconvolutionResult(wks, 3);
				vector vecConvolutedSignal, vecInstrumentResponse, vecDeconvolutionResult;
				vecConvolutedSignal = dsConvolutedSignal;
				vecInstrumentResponse = dsInstrumentResponse;
				// Call function to perform deconvolution
				int iRet = deconvolute(vecConvolutedSignal, vecInstrumentResponse, vecDeconvolutionResult);
				if( 0 != iRet )
				{
					printf("Deconvolution function returned error: %d\n", iRet);
					return;
				}
				// Copy result to dataset
				dsDeconvolutionResult = vecDeconvolutionResult;
				// 
				// The fourth column in the worksheet will now have the result
				// of the deconvolution. The instrument response was a broad asymmetric gaussian
				// and the deconvolution output should be sharp peaks that have been recovered
				// from the signal.
			}		
	Parameters:
		vecSignal 	= [input] vector with Signal data
		vecResponse = [input] vector with Response data
		vecResult 	= [output]vector to return result of deconvolution
		bNormalize 	= [input] true: normalize sum of response elements to unity, false: do not normalize
		bWrap 		= [input] true: wrap response so that max value is at 0th element, false: do not wrap
		bCircular 	= [Input] false: if true, do circular deconvolution, else do linear deconvolution
	Return:
		Returns 0 for no errors, positive number for any FFT-returned error code.
*/
//int deconvolute(vector& vecSignal, vector& vecResponse, vector& vecResult, bool bNormalize = true, bool bWrap = true, bool bCircular = false);
///end REMOVE_CODE_TO_XF

// Comments last updated by ER on 05/26/05
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:fft_real_(global_function)
*/
int fft_real(int nFFT, vector& vSig, FFT_SIGN iSign = FFT_FORWARD);

// Comments last updated by ER on 05/26/05
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:fft_complex_(global_function)
*/
int fft_complex(int nFFT, vector<complex>& vSig, FFT_SIGN iSign = FFT_FORWARD);

///  Comments last updated by Arvin 2006-5-23 ADD_GET_WINDOW_DATA
// Comments last updated by Frank on 08/09/05
//Category last updated by Justin on 2007-04-04
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:get_window_data_(global_function)
*/
int get_window_data( int nWindowMethod, int nSize,vector& vWindow,  double dAlpha = 0, double dBeta = 0);

///  Comments last updated by Raine 2006-5-25
/**$ >Signal Processing>Fourier Transform>FFT
	Remarks:
		Get frequence from time interval.
	Example1:
		void get_frequence_from_interval_ex1()
		{
			int nSize = 10, nRet;
			double interval = 0.1;
			vector vFreq(nSize);
			
			///Get a frequence vector which size is 10 and time interval is 0.1
			///the out put should be {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
			nRet = get_frequence_from_interval(nSize, vFreq, interval);	
			if( 0 != nRet )
			{
				printf("get_frequence_from_interval function returned error: %d\n", nRet);
				return;
			}
		}
	Parameters:
		nSize 	=	[input]		number of points of the frequence 
		vFreq	=	[output]	the result of frequence
		interval=	[input]		the interval of time
	return:
		Returns OE_NOERROR for success or error codes for failure.
*/
int get_frequence_from_interval(int nSize, vector& vFreq, double interval);

///  Comments last updated by Raine 2006-5-25
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:fft_norm_amp_(global_function)
*/
int fft_norm_amp(vector<complex>& vSignal);

///  Comments last updated by Raine 2006-5-25
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:fft_factor_(global_function)
*/
int fft_factor(vector<complex>& vSignal);

///  Comments last updated by Joseph  2007 - 8 - 08
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:fft_shift_(global_function)
*/
int fft_shift(vector<complex>& vSignal, vector& vFreq);

///  Comments last updated by Sandy 2006-6-13
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:undo_fft_shift_(global_function)
*/
///justin 08/23/2006 FIX_UNDO_SHIFT
//int ifft_shift(vector<complex>& vSignal, vector& vFreq);
int undo_fft_shift(vector<complex>& vSignal, vector& vFreq = NULL);
//end 

///  Comments last updated by Raine 2006-5-25
/** >Signal Processing>Fourier Transform
		-------------GCJ 9/1/99 t6908 v6.0227 UNWRAP_PHASE_IN_FFT
*/

///  Comments last updated by Cloud 03/19/2007
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:fft_unwrap_phase_(global_function)
*/
int fft_unwrap_phase(vector& vPhase);

///  Comments last updated by Raine 2006-5-25
/// Category last uapdated by Justin 2007-04-04
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:apply_window_data_(global_function)
*/
///---justin 08/14/2006 GET_COMPENSATING
//int apply_window_data(vector& vSignal, int nType);
int apply_window_data(vector& vSignal, int nType, double* pdCom = NULL);
///end GET_COMPENSATING 

	// Comments last updated by ER on 05/27/05
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:fft_sine_(global_function)
*/
int fft_sine(int nFFT, vector& vSig);

// Comments last updated by ER on 05/27/05
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:fft_cosine_(global_function)
*/
int fft_cosine(int nFFT, vector& vSig);

// Comments last updated by Frank on 08/09/05
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:fft_lowpass_(global_function)
*/
int fft_lowpass(Curve& crvSignal, double dFc);

// Comments last updated by Frank on 08/09/05
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:fft_lowpass_(global_function)
*/
//int lowpass(vector& vecSignal, double dFc, vector& vecTime = NULL);///Forest 09/21/04 QA70-6227 CHANGE_PROTOTYPE
int fft_lowpass(vector& vecSignal, double dFc, vector* vecTime = NULL);

// Comments last updated by Frank on 08/09/05
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:fft_highpass_(global_function)
*/
int fft_highpass(Curve& crvSignal, double dFc, bool bAddOffset = true);

// Comments last updated by Frank on 08/09/05
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:fft_highpass_(global_function)
*/
//int highpass(vector& vecSignal, double dFc, bool bAddOffset = true, vector& vecTime = NULL);///Forest 09/21/04 QA70-6227 CHANGE_PROTOTYPE
//int highpass(vector& vecSignal, double dFc, bool bAddOffset = true, vector* vecTime = NULL);///Cheney 2006-7-12 RENAME_AND_CHANGE_PROTOTYPE
int fft_highpass(vector& vecSignal, double dFc, vector* vecTime = NULL, bool bAddOffset = true);

// Comments last updated by Frank on 08/09/05
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:fft_bandpass_(global_function)
*/
int fft_bandpass(Curve& crvSignal, double dFLow, double dFHigh, bool bAddOffset = true);

// Comments last updated by Frank on 08/09/05
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:fft_bandpass_(global_function)
*/
//int bandpass(vector& vecSignal, double dFLow, double dFHigh, bool bAddOffset = true, vector& vecTime = NULL);///Forest 09/21/04 QA70-6227 CHANGE_PROTOTYPE
//int bandpass(vector& vecSignal, double dFLow, double dFHigh, bool bAddOffset = true, vector* vecTime = NULL); 
///Cheney 2007-7-12 RENAME_AND_CHANGE_PROTOTYPE
int fft_bandpass(vector& vecSignal, double dFLow, double dFHigh, vector* vecTime = NULL, bool bAddOffset = true); 
	
// Comments last updated by Frank on 08/09/05
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:fft_bandblock_(global_function)
*/
int fft_bandblock(Curve& crvSignal, double dFLow, double dFHigh, bool bAddOffset = true);

// Comments last updated by Frank on 08/09/05
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:fft_bandblock_(global_function)
*/
//int bandblock(vector& vecSignal, double dFLow, double dFHigh, bool bAddOffset = true, vector& vecTime = NULL);///Forest 09/21/04 QA70-6227 CHANGE_PROTOTYPE
//int bandblock(vector& vecSignal, double dFLow, double dFHigh, bool bAddOffset = true, vector* vecTime = NULL);///Cheney 2006-7-12 RENAME_AND_CHANGE_PROTOTYPE
int fft_bandblock(vector& vecSignal, double dFLow, double dFHigh, vector* vecTime = NULL, bool bAddOffset = true);

// Comments last updated by Frank on 08/09/05
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:fft_threshold_(global_function)
*/
int fft_threshold(Curve& crvSignal, double dThreshold);

// Comments last updated by Frank on 08/09/05
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:fft_threshold_(global_function)
*/
//int threshold_filter(vector& vecSignal, double dThreshold, vector& vecTime = NULL);///Forest 09/21/04 QA70-6227 CHANGE_PROTOTYPE
int fft_threshold(vector& vecSignal, double dThreshold, vector* vecTime = NULL);


/// Comments last updated by Cloud on 03/19/2007
/**$ >
	Remarks:
    	get time interval information in signal's linking x vector from a GetN treenode
	Parameters:
		tr  		= [input]  GetN treenode that represent complex vector of signal data
		pdInterval 	= [output] pointer to the double variable to receive the time interval
		trReference = [input] reference data range, which should not be used to calculate sampling interval
	Return:
		OE_NOERROR if success, negtive if no X data found or tr invalid, otherwise for errors return 			

*/
/// YuI 10/14/09 QA70-13728-P3 WRONG_AUTOSAMPLING_INTERVAL_IF_OUTPUT_PRODUCES_X_COLUMN
//	int get_fft_interval_by_x_input(const TreeNode& tr, double* pdInterval = NULL);
int get_fft_interval_by_x_input(const TreeNode& tr, double* pdInterval = NULL, const TreeNode& trReference = NULL);
/// end WRONG_AUTOSAMPLING_INTERVAL_IF_OUTPUT_PRODUCES_X_COLUMN


///  Comments last updated by Cloud on 03/19/2007
/**$ >
	Remarks:
		Get Lag sequence from time interval.
	Parameters:
		nSize 		=	[input]	 number of points of the frequence 
		vLag		=	[output] the output vector of Lag
		interval	=	[input]	 the interval of time
		bCircular	=   [input]  the algorithm apply to later Convolution
	return:
		Returns OE_NOERROR for success or error codes for failure.
*/
int get_lag_from_interval(int nSize, vector& vLag, double interval, bool bCircular = false);

//  Comments last updated by Cheney 2006-7-13
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:fft_normalize_response_(global_function)
*/
void fft_normalize_response(vector& vecResponse);

///  Comments last updated by Cheney 2006-7-13
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:fft_wrap_response_(global_function)
*/
void fft_wrap_response(vector& vecResponse);

///Justin 2007-3-22 v8.0587 CHECK_USER_INPUTED_INTERVAL ///move auto_compute_sampling_interval_from_InputData into event_utils.c
///Cheney 2006-7-19 AUTO_COMPUTE_SAMPLING_INTERVAL_FROM_INPUTDATA
//  Comments last updated by Cheney 2006-7-19
/**$ >Signal Processing>Fourier Transform>FFT
	Remarks:
		This function performs auto compute sampling interval from InputData
		by GUI tree if interval value of the tree is missing.
	Parameters:
		trGetN	  = [modify] Input: GUI tree; Output: get interval value if the value is missing.
		lpcszName = [input]  name of node which contains interval value. default is "interval" 
	return:
		OE_NOERROR for success to get parameters value or the value is not missing,
		negtive for failure.
		positive for giveing a fixed value : 1 
*/
//int auto_compute_sampling_interval_from_InputData(TreeNode& trGetN, string strNodeName = "interval");
///AUTO_COMPUTE_SAMPLING_INTERVAL_FROM_INPUTDATA
///Sandy 2006-8-25 parameters of STFT should not be auto computed
/////Cheney 2006-7-19 AUTO_COMPUTE_PARAMS_VALUE

///justin 10/31/2006 OVERLOAD_AUTO_COMPUTE_SAMPLING
///justin 11/21/2006 RENAME_ARGUMENT
//int auto_compute_sampling_interval_from_InputData(const TreeNode& trInput, TreeNode& trInterval, bool bSet = false, double* pdInterval = NULL);
///justin 01/11/2007 APPLY_EDIT_BOX_WITH_AUTO_CHECKE_BOX
//int auto_compute_sampling_interval_from_InputData(const TreeNode& trInput, TreeNode& trInterval, bool bKeepAuto = true, double* pdInterval = NULL);
/**$ 
*/
//int auto_compute_sampling_interval_from_InputData(const TreeNode& trInput, TreeNode& trInterval, bool bKeepAuto = false, double* pdInterval = NULL);
///end APPLY_EDIT_BOX_WITH_AUTO_CHECKE_BOX
///END RENAME_ARGUMENT
///end OVERLOAD_AUTO_COMPUTE_SAMPLING
///justin 11/03/2006 MOVE_INTO_EVET_UTILS
/////justin 10/31/2006 GET_FFT_INPUT_COMPLEX_VECTOR
//int get_fft_input_vector(const TreeNode& trInput, vector<complex>& vx = NULL);
/////end GET_FFT_INPUT_COMPLEX_VECTOR
///end MOVE_INTO_EVET_UTILS
///end CHECK_USER_INPUTED_INTERVAL

///Justin 2007-3-23 v8.0588 MOVE_BACK_FFTUTILIS_BECAUSE_COMPILE_ERROR
/// YuI 10/14/09 QA70-13728-P3 WRONG_AUTOSAMPLING_INTERVAL_IF_OUTPUT_PRODUCES_X_COLUMN
//	int auto_compute_sampling_interval_from_InputData(const TreeNode& trInput, TreeNode& trInterval);
int auto_compute_sampling_interval_from_InputData(const TreeNode& trInput, TreeNode& trInterval, const TreeNode& trReference = NULL);
/// end WRONG_AUTOSAMPLING_INTERVAL_IF_OUTPUT_PRODUCES_X_COLUMN
///end MOVE_BACK_FFTUTILIS_BECAUSE_COMPILE_ERROR

////  Comments last updated by Cheney 2006-7-19
///**$ >Signal Processing>Fourier Transform
		//This function performs auto compute sampling parameters from InputData
		//by GUI tree if parameters value of the tree is missing.
	//Parameters:
		//trGetN	 	 = [modify]Input: GUI tree; Output: get parameters value if value is missing. 
		//lpcszFFT	 = [input] name of node which contains FFT length. default is "fftlen".
		//lpcszWin	 = [input] name of node which contains window size. default is "winlen"
		//lpcszOverlap = [input] name of node which contains overlap value. default is NULL
	//return:
		//true for success to get interval value or the value is not missing,
		//false for failure.
//*/
//bool auto_compute_params_value(TreeNode& trGetN, LPCSTR lpcszFFT = "fftlen", LPCSTR lpcszWin = "winlen", LPCSTR lpcszOverlap = NULL);
///end AUTO_COMPUTE_PARAMS_VALUE

///Cheney 2006-8-4 WINDOW_FILTER
//  Comments last updated by Cheney 2006-7-19
/**$ >Signal Processing>Fourier Transform>FFT Filter
	Remarks:
		This function performs get a window filter.
	Example1:
		void window_filter_ex1()
		{
			int order = 8;
			vector vf;
			
			window_filter(vf, RECTANGLE_WIN, LOW_PASS_FILTERING, order, 100, 30, 30);
		}
	Parameters:
		vFilter	 	 	 = [output]filter's data. 
		nWindowMethod	 = [input] window method. detail could see get_window_data
		nResponseType	 = [input] response type.it can be one of the following,
								   LOW_PASS_FILTERING,	 //	low-pass filtering;
								   HIGH_PASS_FILTERING,	 //	high-pass filtering;
								   BAND_PASS_FILTERING,	 //	band-pass filtering;
								   BAND_BLOCK_FILTERING, //	band-block filtering;
		nOrder 			 = [input] filter's size. should greater than 1.
		dFs 			 = [input] sampling frequency. 
		dLow 			 = [input] lower cutoff frequency. 0<dLow<dFs/2
		dHigh 			 = [input] upper cutoff frequency. 
								   if nResponseType!=LOW_PASS_FILTERING, 0<dLow<dHigh<dFs/2
		dAlpha			 = [input] Alpha parameter of Gaussian window. default is 0.
		dBeta			 = [input] Beta parameter of Kaiser window.. default 0.
	return:
		OE_NOERROR for success to get filter, otherwise for failure.
*/
int window_filter(vector& vFilter, int nWindowMethod, int nResponseType, int nOrder, double dFs, double dLow, double dHigh = 0, double dAlpha = 0, double dBeta = 0);
///end WINDOW_FILTER

//  Comments last updated by Cheney 2006-8-14
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:fft_sampling_resolution_(global_function)
*/
int fft_sampling_resolution(vector* vecTime, double& dTimeStep, double* dInitTime = NULL);

/// Fisher 2008-8-19 QA80-12043 MISSING_75_FUNCTIONS

/**$ >Signal Processing  > Fourier Transform
			This function performs a 2-dimensional Fast Fourier Transform.
	Remarks:
			Data matrix should be of type double. If user have the data	matrix in integer form, 
			user should first transform it to double using the member function of 
			matrixbase "CastToDouble".
	Example:
		This example computes the 2 dimension fast fourier transform of the matrix mRe.
	
    #include <matrix.h>
	void FFT2_ex1()
	{
		matrix<double> mRe = {{-1.486782,-0.530723,0.139563,-1.018762},
	                       {-0.831440 ,0.938971,-0.760729,1.620196},
	                       {- 0.7794,-0.5500 ,0.6640, -0.4333},
	                       {-2.0366,1.9275,0.3313,1.1098}};
	   
		matrix <complex> mResult;
	
		int ii,jj,Err;
	
		//test function FFT2 for arbitrary source matrix
		Err = FFT2(mRe, mResult);
	
		if ( 0 != Err ) 
		{
        	ASSERT(false);
        	printf("two-dimension FFT2 fails\n");
		}
		else
		{
			for(ii = 0; ii < mResult.GetNumRows();  ii++)
			{
				for(jj = 0; jj < mResult.GetNumCols(); jj++)
			    	printf("(%f, %fi)  ",mResult[ii][jj].m_re,mResult[ii][jj].m_im);
				printf("\n");
			}
		}
	}
	
	The output is as following:
		(-0.424101, 0.000000i)  (-1.377089, -0.126954i)  (-1.955942, 0.000000i)  (-1.377089, 0.126954i)  
		(-0.449501, 0.091251i)  (0.328995, -0.725482i)  (-0.166409, -0.147816i)  (-0.420468, -0.423113i)  
		(-1.573601, 0.000000i)  (-0.157784, -0.058716i)  (2.491026, 0.000000i)  (-0.157784, 0.058716i)  
		(-0.449501, -0.091251i)  (-0.420468, 0.423113i)  (-0.166409, 0.147816i)  (0.328995, 0.725482i)  
	
	Parameters:
			matSource: The data source matrix
			matFFT2Result: The matrix containing the 2 dimension FFT results
			nRowProcess:
			nColProcess: The number of rows or columns user provided. If they are -1, there is no padding
	 					or truncating. If they are more than the sizes of the matrix, the function will pad zero to meet the size
						If less than, it will truncate the data matrix.
	Return:
			If succeed, it will return 0;	Otherwise it returns error indications.
			Error:
			-1: Provided column number or row number. Must be -1 or positive integer
			-2: The data source matrix is empty 
			-3: When calling member function, it fails.
			-4: When calling GetReal or GetImage member function of matrix class, it failed.
  
*/
int FFT2(matrix& matSource, matrix<complex>& matFFT2Result, int nRowProcess  = -1, int nColProcess = -1);

/**$ >Signal Processing  > Fourier Transform
			This function performs a 2-dimensional Fast Fourier Transform.
	Remarks:
			Data matrix should be of type complex. If user have the data matrix in integer form, 
			user should first transform it to complex. 
	Example:
		This example computes the 2 dimension fast fourier transform of the matrix mSource. 
		
	void FFT2_ex1()
	{
		matrix<double> mRe = {{-1.486782,-0.530723,0.139563,-1.018762},
	                       {-0.831440 ,0.938971,-0.760729,1.620196},
	                       {- 0.7794,-0.5500 ,0.6640, -0.4333},
	                       {-2.0366,1.9275,0.3313,1.1098}};
	
		matrix<double> mIm = {{2.482,3.5723,0.9553,-1.01842},
	                       {-1.8317 ,4.38271,-1.0729,1.226},
	                       {0.7724,-0.5540 ,1.540, -1.333},
	                       {2.0456,-1.935,2.6513,1.2708}};
	         
		matrix <complex> mSource, mResult;
	
		mSource.MakeComplex(mRe,mIm);
	
		int ii,jj,Err;
	
		//test function FFT2 for arbitrary source matrix
		Err = FFT2(mSource, mResult);
	
		if ( 0 != Err ) 
		{
        	ASSERT(false);
        	printf("two-dimension FFT2 fails\n");
		}
		else
		{
			for(ii = 0; ii < mResult.GetNumRows();  ii++)
			{
				for(jj = 0; jj < mResult.GetNumCols(); jj++)
			    	printf("(%f, %fi)  ",mResult[ii][jj].m_re,mResult[ii][jj].m_im);
				printf("\n");
			}
		}
	}
	
	The output is as following:
		(-0.424101, 3.288348i)  (-0.046932, -0.278304i)  (-1.955942, 0.482652i)  (-2.707247, -0.024397i)  
		(-0.781648, 1.482696i)  (1.243650, -1.742534i)  (-3.635011, -0.976811i)  (-1.411672, 1.741090i)  
		(-1.573601, -0.080057i)  (1.196919, 0.472184i)  (2.491026, 2.058758i)  (-1.512486, 0.589616i)  
		(-0.117354, 1.300194i)  (0.570738, 2.587315i)  (3.302194, -0.681179i)  (-0.585660, -0.291571i)  

	Parameters:
			matSource: The data source matrix
			matFFT2Result: The matrix containing the 2 dimension FFT results
			nRowProcess:
			nColProcess: The number of rows or columns user provided. If they are -1, there is no padding
	 					or truncating. If they are more than the sizes of the matrix, the function will pad zero to meet the size
						If less than, it will truncate the data matrix.
	Return:
			If succeed, it will return 0;	Otherwise it returns error indications.
			Error:
			-1: Provided column number or row number. Must be -1 or positive integer
			-2: The data source matrix is empty 
			-3: When calling member function, it fails.
			-4: When calling GetReal or GetImage member function of matrix class, it failed.
  
*/
int FFT2(matrix<complex>& matSource, matrix<complex>& matFFT2Result, int nRowProcess  = -1, int nColProcess = -1);

/**$ >Signal Processing  > Fourier Transform
			This function performs a 2-dimensional inverse Fast Fourier Transform.
	Remarks:
			Data matrix should be of type complex. If user have the data matrix in integer form, 
			user should first transform it to complex. 
	Example:
		This example computes the 2 dimension inverse fast fourier transform of the matrix mSource. 
		
	void IFFT2_ex1()
	{
		matrix<double> mRe = {{-1.486782,-0.530723,0.139563,-1.018762},
	                       {-0.831440 ,0.938971,-0.760729,1.620196},
	                       {- 0.7794,-0.5500 ,0.6640, -0.4333},
	                       {-2.0366,1.9275,0.3313,1.1098}};
	
		matrix<double> mIm = {{2.482,3.5723,0.9553,-1.01842},
	                       {-1.8317 ,4.38271,-1.0729,1.226},
	                       {0.7724,-0.5540 ,1.540, -1.333},
	                       {2.0456,-1.935,2.6513,1.2708}};
	         
		matrix <complex> mSource, mResult;
	
		mSource.MakeComplex(mRe,mIm);
	
		int ii,jj,Err;
	
		Err = IFFT2(mSource, mResult);
	
		if ( 0 != Err ) 
		{
			ASSERT(false);
			printf("two-dimension IFFT2 fails\n");
		}
		else
		{
			for(ii = 0; ii < mResult.GetNumRows();  ii++)
			{
				for(jj = 0; jj < mResult.GetNumCols(); jj++)
			    	printf("(%f, %fi)  ",mResult[ii][jj].m_re,mResult[ii][jj].m_im);
				printf("\n");
			}
		}
	}
	
	The output is as following:
	    (-0.424101, 3.288348i)  (-2.707247, -0.024397i)  (-1.955942, 0.482652i)  (-0.046932, -0.278304i)  
		(-0.117354, 1.300194i)  (-0.585660, -0.291571i)  (3.302194, -0.681179i)  (0.570738, 2.587315i)  
		(-1.573601, -0.080057i)  (-1.512486, 0.589616i)  (2.491026, 2.058758i)  (1.196919, 0.472184i)  
		(-0.781648, 1.482696i)  (-1.411672, 1.741090i)  (-3.635011, -0.976811i)  (1.243650, -1.742534i)  
	
	Parameters:
			matSource: The data source matrix
			matIFFT2Result: The matrix containing the 2 dimension inverse FFT results
			nRowProcess:
			nColProcess:The number of rows or columns user provided. if they are -1, there are no padding
	 					or truncating. if they are larger than the size of the matrix, the function will pad zero to meet
						the size. If less than, it will truncate the data matrix.
	Return:
			If succeed, it will return 0;	Otherwise it returns error indications.
			Error:
			-1: Provided column number or row number. Must be -1 or positive integer
			-2: The data source matrix is empty 
			-3: When calling member function, it fails.
			-4: When calling GetReal or GetImage member function of matrix class, it failed.
*/
int IFFT2(matrix<complex>& matSource, matrix<complex>& matIFFT2Result, int nRowProcess  = -1, int nColProcess = -1);

//Comments last updated by Sophy on 6/16/2009
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:FFT_(global_function)
*/
int FFT(matrix& matSource, matrix<complex>& matFFTResult, int nColProcess = -1);

//Comments last updated by Sophy on 6/16/2009
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:FFT_(global_function)
*/
int FFT(matrix<complex>& matSource, matrix<complex>& matFFTResult, int nColProcess = -1);

/**$ >Signal Processing  > Fourier Transform
			This function performs 1-dimensional inverse Fast Fourier Transform on each row of data in a matrix.
	Remarks:
			Data matrix should be of type complex. If user have the data matrix in integer form, 
			user should first transform it to complex.

	Example:
		int IFFT_ex1()
		{
			matrix matSource = {{1,2,3,4,5},{6,7,8,9,10}};
			
			int nRet;
			matrix<complex> matResult;
			nRet = FFT(matSource,matResult, -1);
			if(nRet)
				return nRet;
			int nNumCols = matResult.GetNumCols();
			int nNumRows = matResult.GetNumRows();
			int ii, jj;
			for( ii = 0; ii < nNumRows; ii++)
			{
				for(jj = 0; jj < nNumCols; jj++)
					printf("%f + %f i",matResult[ii][jj].m_re, matResult[ii][jj].m_im);
				printf("\n");
			}

			printf("now do the padding\n");
			nRet = FFT(matSource,matResult, 14);
			if(nRet)
				return nRet;
			//after The padding	

			nNumCols = matResult.GetNumCols();
			nNumRows = matResult.GetNumRows();
			
			for( ii = 0; ii < nNumRows; ii++)
			{
				for(jj = 0; jj < nNumCols; jj++)
					printf("%f + %f i",matResult[ii][jj].m_re, matResult[ii][jj].m_im);
				printf("\n");
			}
			printf("now do the truncting\n");
			//after truncting
			nRet = FFT(matSource,matResult, 6);
			if(nRet)
				return nRet;
			nNumCols = matResult.GetNumCols();
			nNumRows = matResult.GetNumRows();
			
			for( ii = 0; ii < nNumRows; ii++)
			{
				for(jj = 0; jj < nNumCols; jj++)
					printf("%f + %fi ",matResult[ii][jj].m_re, matResult[ii][jj].m_im);
				printf("\n");
			}
			
			return nRet;
		}
	Parameters:
			matSource:The data source matrix
			matIFFT2Result: The matrix containing the 1 dimension inverse FFT results
			nColProcess:The number of columns user provided. if it is -1, there is no padding
	 					or truncating. if it is more than the size of the  matrix, it will pad zero to meet the size
						if less than, it will truncate the data matrix.
	Return:
			If succeed, it will return 0;	Otherwise it returns error indications.
			Error:
			-1: Provided column number or row number must be -1 or positve integer
			-2: The data source matrix is empty 
			-3: When calling member function, it fails.
			-4: When calling GetReal or GetImage member function of matrix class, it failed.
  
*/

// ER 01/29/03 QA70_3802	ADD_VECTOR_FFT_IFFT
int IFFT(matrix<complex>& matSource, matrix<complex>& matFFTResult, int nColProcess = -1);

//Comments last updated by Sophy on 6/16/2009
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:FFT_(global_function)
*/

// ER 01/29/03 QA70_3802	ADD_VECTOR_FFT_IFFT
int FFT(vector<complex>& vecSource, vector<complex>& vecFFTResult);

/**$ >Signal Processing  > Fourier Transform
			This function performs 1-dimensional inverse Fast Fourier Transform on data in a complex vector.
	Remarks:
			Data vector should be of type complex. If user have the data vector in integer or double form, 
			user should first transform it or copy it to a complex vector.
			This function in turn calls the matrix-based FFT function.

	Example:
		int IFFT_ex1()
		{
			vector vR = { 1,2.5,3.5,2,1.0,2.3 };
			vector vI = { 1,0.5,1.0,0.8,3.1,0.3 };
			vector <complex> vC(vR, vI), vResult(vC.GetSize());
	
			//tedt 1d ifft function on data in a complex vector
			int Err = IFFT(vC, vResult);
	
			if ( 0 != Err )
			{
	       		ASSERT(false);
	       		printf("one-dimension IFFT fails\n");
			}
			else
			{
				for(int ii = 0; ii < vResult.GetSize();  ii++)
				{
				   	printf("(%f, %fi)  ",vResult[ii].m_re,vResult[ii].m_im);
			    	printf("\n");
				}
			}
			return Err;
		}
		
		The output is as following:
			(5.021454, 2.735264i)  
			(0.324740, 0.362634i)  
			(-1.486782, -1.078534i)  
			(-0.530723, 1.428869i)  
			(0.139563, 0.547811i)  
			(-1.018762, -1.546554i)  
			
			
	Parameters:
			vecSource:The data source vector
			vecIFFTResult: The vector containing the 1-dimensional inverse FFT results
	Return:
			If succeed, it will return 0;	Otherwise it returns error indications.
			Error:
			-5: source vector is of zero length
			n:	other error codes returned by matrix-based FFT function
  
*/
int IFFT(vector<complex>& vecSource, vector<complex>& vecFFTResult);

/// end MISSING_75_FUNCTIONS

///------ Folger 04/17/09 QA80-13429 RECREATE_X_DATA_FOR_NOT_EVEN_SPACE_INPUT_X
void	recreate_even_space_time_vector(vector& vTime, double rInc);
///------ End RECREATE_X_DATA_FOR_NOT_EVEN_SPACE_INPUT_X

/// Fisher	07/29/09 QA80-14034 	SET_2DFFT_FREQUENCY_DOMAIN
void	get_sampling_interval_2d(MatrixObject &mo, double &dx, double &dy);
void	set_frequency_domain_2d(MatrixObject &mo, double dx, double dy, int shift);
/// SET_2DFFT_FREQUENCY_DOMAIN

/// Iris 10/20/2009 ADD_FFT_PREVIEW_FOR_DECIMATE_XF	
bool show_FFT_preview(TreeNode& trGetN, PageBase& pgTemp, Worksheet& wksTemp, XYRange& xyResampled, double dFactor);
///end ADD_FFT_PREVIEW_FOR_DECIMATE_XF

///-----Kit 10/26/2010 ORG-1227-P3 SUPPORT_OTHER_FFT_TOOL_SHOW_UNITS_ON_REPORT_TABLE
class ShowUnitsHelperBase
{
public:
	ShowUnitsHelperBase(const DataRange &dr);
	bool	ShowUnitsRowOnReportTable(Worksheet &wksFFT, const ReportTable &rtFFT);
protected:
	virtual	bool	CreateReportUnitStr(int nRDID, string &strUnit);
	bool	CheckUnitIsCompoiste(const string &strUnit);
	bool	AddParenthesis(string &strUnit);
	bool	HandleReciprocalCase(string &strUnit);
private:
	bool	updateInputWksAndInputColIndex();
	bool	updateUnitStr();
protected:	
	string 		m_strUnitX;
	string		m_strUnitReal;
	string		m_strUnitImag;

private:
	DataRange	m_drInput;
	int			m_nRealColIndex;
	int			m_nImagColIndex;
	Worksheet	m_wksInput;
};
///-----End SUPPORT_OTHER_FFT_TOOL_SHOW_UNITS_ON_REPORT_TABLE

#endif		/// _FFT_UTILS_H
