/*------------------------------------------------------------------------------* * File Name:Analysis_utils.h * * Creation: CPY 3/11/03 * * Purpose: Origin's basic internal analysis routines * * Copyright (c) Originlab Corp. 2003 * * All Rights Reserved * * * * Modification Log: * *------------------------------------------------------------------------------*/ #ifndef _ANALYSIS_UTILS_H #define _ANALYSIS_UTILS_H /** >Analysis Converts regular XYZ data to a matrix. If asked for, data is examined for deviations. Example: //This example fill a matrix with values in Data1. //For this samples to work, Data1 must exist in the project contains 3 column A, B, C void run_convert_regular_xyz_to_matrix() { Dataset dsX("Data1_A"), dsY("Data1_B"), dsZ("Data1_C"); vector vecX(dsX), vecY(dsY), vecZ(dsZ); MatrixLayer ml; //Create a new Matrix to get the result ml.Create(); Matrix matData(ml); double dXmax, dXmin; vecX.GetMinMax(dXmin, dXmax); //Get the maximum and minimum values of X double dYmax, dYmin; vecY.GetMinMax(dYmin, dYmax); //Get the maximum and minimum values of Y convert_regular_xyz_to_matrix(vecX, vecY, vecZ, matData, dXmin, dXmax, dYmin, dYmax); } Parameters: vecX,Y,Z: Input: regular XYZ data dXmin, dXmax: min, max of x data - can use for setting coordinates of Matrix object dYmin, dYmax: min, max of y data - can use for setting coordinates of Matrix object bCheckData: true: check data for irregularities; false: do no checking If user knows data is perfectly regular, can set to false for faster operation Return: 0: success 1: XYZ vectors are of unequalsize, or result matrix smaller than 2x2 2: could not find steps in data 3: groups in x/y do not match group length in y/x 4: too much deviation in x/y data */ int convert_regular_xyz_to_matrix(vector& vecX, vector& vecY, vector& vecZ, matrix& matData, double& dXmin, double& dXmax, double& dYmin, double& dYmax, bool bCheckData = true); /** >Analysis Performs gridding of random XYZ data. The gridding is performed by calling NAG functions. Two gridding methods, Renka-Cline and Modified Shepard's method are available. For more details on these methods, see documentation for NAG function e01_sac. Example: int iRet = random_gridding_nag(vecX, vecY, vecZ) // Renka-Cline method int random_gridding_nag(vecX, vecY, vecZ, 1) // Shepard's method Parameters: vecX,Y,Z: Input: random XYZ data matResult: matrix with gridded data dXmin, dXmax: min, max of x data - can use for setting coordinates of Matrix object dYmin, dYmax: min, max of y data - can use for setting coordinates of Matrix object iMethod: 0: Renka-Cline gridding; <>0: Modified Shepard's method dQIL: Quadratic Interpolant Locality - used only by Shepard's method dWFL: Weight Function Locality - used only by Shepard's method Return: 0: success -1: Error in creating matrix NAG error codes: 70: Parameter method had an illegal value. 11: The number of points is less than 3. 73: Memory allocation failed. 245: All the (x,y) pairs are collinear. 246: Data pair is not unique. Duplicate points are found in the (x,y) pair. 247: Invalid dQIL and dWFL for Shepard's method. 249: (Warning)The minimum number of data points that lie within the radius of any node is smaller that the interpolant may be unsatisfactory in regions where the data points are sparse. 251: (Warning)The evaluation point lies outside the triangulation boundary. The returned value was computed by extrapolation. 252: On entry,the interpolant cannot be evaluted because the evaluation point is outside the support region of the input data points. See Also: convert_regular_xyz_to_matrix */ int convert_random_xyz_to_matrix_nag(vector& vecX, vector& vecY, vector& vecZ, matrix& matResult, double& dXmin, double& dXmax, double& dYmin, double& dYmax, int iMethod = 0, double dQIL = 1, double dWFL = 1); /** >Analysis Removes duplicate points from XYZ data. Duplicates are replaced with mean Z value. Example: //This example removes the duplicated values in Data1. //For this samples to run, Data1 should exist in the project with A, B, C columns. void run_xyz_remove_duplicates() { Dataset dsX("Data1_A"), dsY("Data1_B"), dsZ("Data1_C"); vector vecX(dsX), vecY(dsY), vecZ(dsZ); xyz_remove_duplicates(vecX, vecY, vecZ); dsX = vecX; dsY = vecY; dsZ = vecZ; } Parameters: vecX,Y,Z: Input: XYZ data; Output: XYZ vectors with duplicates removed Return: 0: success 1: XYZ vectors are of incorrect length */ int xyz_remove_duplicates(vector& vecX, vector& vecY, vector& vecZ); /** >Analysis Converts sparse XYZ data to a matrix. Sparse data is regular data with some rows missing. Example: //This example convert Data1_A, Data1_B, Data1_C into a sparse matrix. //For this sample to run, Data1 with column A, B, C must exist. void run_convert_sparse_xyz_to_matrix() { Dataset dsX("Data1_A"), dsY("Data1_B"), dsZ("Data1_C"); vector vecX(dsX), vecY(dsY), vecZ(dsZ); MatrixLayer ml; ml.Create(); // Create a new matrix to get the result Matrix matData(ml); double dXend, dXbegin; double dYend, dYbegin; double dXstep; double dYstep; convert_sparse_find_min_max_step(vecX, dXbegin, dXend, dXstep); //Find the step convert_sparse_find_min_max_step(vecY, dYbegin, dYend, dYstep); //Find the step convert_sparse_xyz_to_matrix(vecX, vecY, vecZ, matData, dXbegin, dXend, dXstep, dYbegin, dYend, dYstep); } Parameters: vecX,Y,Z: Input: regular XYZ data matResult: Output: resulting matrix dXmin, dXmax: dXStep: Input: min, max and stepsize in X. Call convert_sparse_find_min_max_step to estimate these values. dYmin, dYmax: dYStep: Input: min, max and stepsize in Y. Call convert_sparse_find_min_max_step to estimate these values. iPrecision: Input: precision used to locate values; same as under Data_list() function Return: 0: All points were converted -1: xyz vectors are of different/incorrect size -2: Matrix size too large - could be due to very small step value -3: Error in creating matrix object positive: Number of points that were discarded */ int convert_sparse_xyz_to_matrix(vector& vecX, vector& vecY, vector& vecZ, matrix& matResult, double dXbegin, double dXend, double dXstep, double dYbegin, double dYend, double dYstep, int iPrecision = 8); /** >Analysis Compute min, max and step value for sparse matrix conversion. Example: int iRet = convert_sparse_find_min_max_step(vec, dMin, dMax, dStep); Parameters: vec: vector with data dMin, dMax, dStep: min, max and step values Return: 0: success See Also: convert_sparse_xyz_to_matrix */ int convert_sparse_find_min_max_step(vector& vec, double& dMin, double& dMax, double& dStep); /** >Curve Find Worksheet and Column names from a Curve Example: //This example get the dataset name of the curve in Graph1. //For this sample to work, Graph1 must exist in the project. void run_curve_get_wks_col_names() { GraphLayer gl("Graph1", 0); //Get the first layer of Graph1 if(gl) { DataPlot dp = gl.DataPlots(0); // Get first data plot in graph layer if(dp) // If valid DataPlot... { Curve crv(dp); // Get Curve from DataPlot string strX, strY, strWks; strWks = curve_get_wks_col_names(crv, strX, strY); out_str("The first DataPlot in Graph1: "); out_str("X: "+ strWks + "_" + strX); out_str("Y: "+ strWks + "_" + strY); } } } Parameters: cuv = [in] Curve to find info about strX = [out] X column name, can be empty if Curve has no X column strY = [out] Y column name. Return: name of the Worksheet, will be empty if input Curve is invalid */ string curve_get_wks_col_names(const curvebase& cuv, string& strX, string& strY); /** >Curve Search the layer where two curves are both plotted. Parameters: cuv1 = [in] Curve to try to add to another curve's layer cuv2 = [in] Curve that is likely already plotted in some layer glayerFound = [out] Graph that cuv2 is currently plotted Example: if(cuvFit) { GraphLayer gl; if(!curve_both_in_layer(cuvFit, cuvData, gl) && gl) // there maybe many, we will just use 1st for now { // cuvData plotted in gl but cuvFit not, so we will make the plot int nPlot = gl.AddPlot(cuvFit, IDM_PLOT_LINE); DataPlot dp = gl.DataPlots(nPlot); dp.SetColor(1); // set to red } } Return: FALSE if not in same layer, or cuv2 not plotted at all Remark: glayerFound can be set to a layer to search first, or it can be let uninitialized */ bool curve_both_in_layer(const curvebase& cuv1, const curvebase& cuv2, GraphLayer& glayerFound); /** >Curve find the input curve layer and plot the result curve Parameters: cuvResult = [in] Curve to plot cuvInput = [in] reference Curve to find where to plot the cuvResult trInput = [in] if given, this will provide the graph layer location to plot cuvResult nColor = [in] color of the cuvResult curve bRescale = [in] rescale layer or not Example: //This example shows how to plot Data1_C to the same graph layer as Data1_B in red. //For this sample codes to run, a worksheet named "Data1" with column B and C //should exist in the current project and a graph with Data1_B plotted exists too. void run_curve_update() { Curve crvPlotted( "Data1_B" ); Curve crvToBePlot( "Data1_C" ); TreeNode trInput; int nColor = 1; //Red if(crvPlotted && crvToBePlot) { curve_update(crvToBePlot, crvPlotted, trInput, nColor); } } Return: TRUE if correct layer is found and cuvResult is plotted successfully */ bool curve_update(curvebase& cuvResult, const curvebase& cuvInput, const TreeNode& trInput, int nColor, bool bRescale = false); /** >Curve It searches for the dataplot containing the given curve. If found, just refreshes the graph page, otherwise it adds the curve to the first layer of the page. Parameters: cuv=[in] the input curve nColor=[in] nthe color the curve should have. gpg=[in] the graph page in which to look for the curve. bRescale=[in] to rescale the layer with the curve or not. Example: //This example add curve Data1_B to Graph1. //For this sample codes to run, Graph1 should exist in the current project. void run_curve_update_in_page() { Curve crvPlotted( "Data1_B" ); GraphPage gp1( "Graph1" ); int nColor = 0; // Black if(gp1 && crvPlotted) { curve_update_in_page(crvPlotted, nColor, gp1); } } Returns: TRUE if OK, otherwise FALSE. */ bool curve_update_in_page(curvebase& cuv, int nColor, GraphPage &gpg, bool bRescale = false); /** >Curve It looks for the curve in the graph page. Parameters: cuv=[in] the curve to look for gpg=[in] the graph page to look in. pnLayerIndex=[in] optional pointer to an integer to receive the index of the layer in which the curve was found pnDataPlotIndex=[in] optional pointer to an integer to receive the index of the dataplot in the layer if found. Example: //This example use function curve_in_page_get_indices() to check whether Data1_B //exists in Graph1. For this sample to work, Data1_B and Graph1 should exist. void run_curve_in_page_get_indices() { Curve crvPlotted( "Data1_B" ); GraphPage gp1( "Graph1" ); if(crvPlotted && gp1) { bool bOK = curve_in_page_get_indices(crvPlotted, gp1); if(bOK) { out_str("Data1_B exists in Graph1."); } else { out_str("Data1_B does not exist in Graph1."); } } } Returns: TRUE if found, otherwise FALSE. */ BOOL curve_in_page_get_indices(const curvebase& cuv, const GraphPage &gpg, int *pnLayerIndex = NULL, int *pnDataPlotIndex = NULL); /** >Curve It adds the curve cuv to the layer grl. Parameters: cuv=[in] the input curve grl=[in] the layer to add the curve to. nColor=[in] nthe color the curve should have. bRescale=[in] to rescale the layer with the curve or not. nPlotType=[in] the plot type of the curve to add. Example: //This example add Data1_B to the first layer of Graph1. //For this example to run, Graph1 should exist in the current project. void run_add_curve_to_graph_layer() { Curve crvPlotted( "Data1_B" ); GraphLayer gl( "Graph1", 0 ); if(crvPlotted && gl) { bool bOK = add_curve_to_graph_layer(crvPlotted, gl); if(bOK) { out_str("Success in adding Data1_B to Graph1."); } else { out_str("Fail to add Data1_B to Graph1."); } } } Returns: TRUE if OK, otherwise FALSE. */ bool add_curve_to_graph_layer(curvebase& cuv, GraphLayer &grl, int nColor = 2, bool bRescale = false, int nPlotType = IDM_PLOT_LINE); /** >Curve check if Curve is in a graph layer and return its plot index if true Parameters: cuv = [in] Curve to test gl = [in] graph layer to test Example: //This example return the index of Data1_B in Graph1. //For this sample to work, Graph1 and Dataset Data1_B must exist in the project. void run_curve_in_layer_get_index() { Curve crvPlotted( "Data1_B" ); GraphLayer gl( "Graph1", 0 ); if(crvPlotted && gl) { int nIndex = curve_in_layer_get_index(crvPlotted, gl); out_int("The index of Data1_B in Graph1 is ", nIndex ); } } Return: plot index if in layer, or -1 if not */ int curve_in_layer_get_index(const curvebase& cuv, const GraphLayer& gl); /** >Curve add to TreeNode the X and Y dataset names of the given curve Parameters: cuv = [in] Curve to get names from trNode = [out] tree node to add the needed info Example: //This example show the info. of the curve. //For this sample to work, dataset Data1_B should exist. #include void run_set_curve() { Curve crvPlotted( "Data1_B" ); Tree trNode; if(crvPlotted) { bool bOK = set_curve(crvPlotted, trNode); if(bOK) { out_tree(trNode); } } } Return: TRUE if success See Also: set_active_layer */ bool set_curve(const curvebase& cuv, TreeNode& trNode); /** >Graph Window add to TreeNode the name of the active graph page and the active layer number Parameters: trNode = [out] tree node to add the needed info Return: TRUE if the active layer is a graphic layer, FALSE if no active graph layer available See Also: get_graph_layer */ bool set_active_layer(TreeNode& trNode); /** >Graph Window retrive the graph layer from the tree node Parameters: trNode = [in] tree node that may contains the needed info prepared by set_active_layer Example: //This example get the active graph layer. void run_get_graph_layer() { GraphPage gp; gp.Create(); Tree trNode; set_active_layer(trNode); //Get the Info. of the active layer GraphLayer gl = get_graph_layer(trNode); ASSERT(gp.GetName() == gl.GetPage().GetName()); out_str("The active graph layer is: " + gl.GetPage().GetName() + "(" + gl.GetIndex() + ")"); } Return: a valid graph layer if successful See Also: set_active_layer */ GraphLayer get_graph_layer(const TreeNode& trNode); /** >Graph Window set the given layer to be active layer, if page not open, will open it to be active page as well Parameters: layr = [in] typically a GraphLayer to be set as active Example: GraphLayer gl("Graph1",0); set_active_layer(gl); Return: true if successful See Also: set_active_layer */ bool set_active_layer(Layer& layr); /**# >Curve prepare a treenode with proper info for the given curve Parameters: cuvInput = the data curve that we will be using trInput = a tree branch that has a Range1 branch that we will need to initialize i1 = beginning drawing range of the cuvInput i2 = ending drawing range of the cuvInput, inclusive hWndRet = only if bNeedInit = false, the graph window's handle where the cuvInput is activated bNeedInit = true will init the trInput node, = false will make use the trInput to activate the graph layer Example: //This example prepare the plotting of Data1_B. //For this sample to run, Data1_B should exist in the project. void run_set_curve_input() { Curve crv("Data1_B"); Tree trInput; int iBegin, iEnd; HWND hWndRet; set_curve_input(crv, trInput, iBegin, iEnd, hWndRet); out_str("Data1_B will be plotted into "+trInput.Page.strVal); } Return: true if the cuvInput is full range, false if cuvInput has selected subrange. */ bool set_curve_input(const curvebase& cuvInput, TreeNode& trInput, int& i1, int& i2, HWND& hWndRet, bool bNeedInit = true); /** >Curve duplicate the active curve in the active graph layer so that analysis routine like derivatives and smoothing can be performed on the copied curve Parameters: lpcszNewColName = name of the Y column for the copied curve bReuseIfInWks = option to always create new copy of can reuse if named column is already in the same worksheet as the original Example: //This example copy the active curve Data1_B in Graph1. //For this sample to run, Data1_B and Graph1 should exist. void run_curve_duplicate_active() { Curve crv("Data1_B"); GraphLayer gl("Graph1", 0); if(crv && gl) { add_curve_to_graph_layer(crv, gl); //Add the curve to the graphlayer set_active_layer(gl); //Set the graphlayer to active Curve crvCopy = curve_duplicate_active(); if(crvCopy) { out_str("Copy successfully."); } } } Return: NULL if no active graph layer with active curve found, or if the operation failed */ curvebase& curve_duplicate_active(LPCSTR lpcszNewColName = NULL, bool bReuseIfInWks = false); #endif //_ANALYSIS_UTILS_H