📄 analysis_utils.c
字号:
/*------------------------------------------------------------------------------*
* File Name:Analysis_utils.c *
* Creation: CPY 3/11/03 *
* Purpose: Origin's basic internal analysis routines *
* Copyright (c) Originlab Corp. 2003 *
* All Rights Reserved *
* *
* Modification Log: *
*------------------------------------------------------------------------------*/
#include <origin.h> // main Origin C header that is precompiled and already include most headers
////////////////////////////////////////////////////////////////////////////////////
#define _DBINT(_STR, _INT) //out_int(_STR, _INT);
#define _DBMGS(_STR) //out_str(_STR);
#define MAX_MATRIX_POINTS 10000000
bool set_curve_input(const curvebase& cuvInput, TreeNode& trInput, int& i0, int& imax, HWND& hWndRet, bool bNeedInit)// = true);
{
bool bFullRange = cuvInput.GetSourceRange(i0, imax)? false:true;
if(bNeedInit) // not supplied, we need to init trInput
{
set_active_layer(trInput);
set_curve(cuvInput, trInput);
}
else
{
if(!trInput.Range1.UseRange.IsValid())
trInput.Range1.UseRange.nVal = 0;
bFullRange = trInput.Range1.UseRange.nVal > 0? false:true;
// we need to set cuvInput active
GraphLayer gl = get_graph_layer(trInput);
if(gl)
{
set_active_layer(gl);
Page pg = gl.GetPage();
if(pg)
hWndRet = pg.GetWindow().GetSafeHwnd();
string str;
str.Format("set %s -a",cuvInput.GetName());
gl.LT_execute(str);
}
}
return bFullRange;
}
// add to TreeNode the X and Y dataset names of the given curve
bool set_curve(const curvebase& cuvInput, TreeNode& trNode)
{
if(!cuvInput)
return false;
if(!trNode)
return false;
int i0 = 0, imax = 0;
trNode.Range1.UseRange.nVal = cuvInput.GetSourceRange(i0, imax) ? 1 : 0;
trNode.Range1.R1.nVal = cuvInput.GetLowerBound();
trNode.Range1.R2.nVal = cuvInput.GetUpperBound();
trNode.Range1.Ydata.strVal = cuvInput.GetName();
Dataset dsX;
if(cuvInput.AttachX(dsX))
trNode.Range1.Xdata.strVal = dsX.GetName();
else
trNode.Range1.Xdata.strVal = "";
return true;
}
// add to TreeNode the name of the active graph page and the active layer number
bool set_active_layer(TreeNode& trNode)
{
GraphPage gpg = Project.Pages();
if(gpg)
{
GraphLayer glyr = Project.ActiveLayer();
trNode.Page.strVal = gpg.GetName();
trNode.Layer.nVal = glyr.GetIndex();
return true;
}
return false;
}
//set the given layer to be active layer, if page not open, will open it to be active page as well
bool set_active_layer(Layer& layr)
{
if(!layr)
return false;
Page pg = layr.GetPage();
if(pg)
{
pg.SetShow();
string strTemp = "page.active=";
strTemp += layr.GetIndex() + 1;//need to labtalk is 1 offset
pg.LT_execute(strTemp);
return true;
}
return false;
}
// retrive the graph layer from the tree node
GraphLayer get_graph_layer(const TreeNode& trNode)
{
GraphLayer gl;
if(trNode)
{
TreeNode trPage = trNode.Page;
if(trPage)
{
GraphPage gpg(trPage.strVal);
if(gpg)
{
TreeNode trTemp = trNode.Layer;
if(trTemp)
{
int nIndex = trTemp.nVal;
if(nIndex >= 0 && nIndex < gpg.Layers.Count())
{
gl = gpg.Layers(nIndex);
return gl;
}
}
}
}
}
return gl;
}
int curve_in_layer_get_index(const curvebase& cuv, const GraphLayer& gl)
{
int ii = 0;
foreach(DataPlot dp in gl.DataPlots)
{
string strName = dp.GetDatasetName();
if(strName.CompareNoCase(cuv.GetName()) == 0)
return ii;
ii++;
}
return -1;
}
BOOL curve_in_page_get_indices(const curvebase& cuv, const GraphPage &gpg, int *pnLayerIndex, int *pnDataPlotIndex)
{
int nLayer = 0;
foreach(GraphLayer gl in gpg.Layers)
{
int nDPIndex = curve_in_layer_get_index(cuv, gl);
if (0 <= nDPIndex)
{
if (pnLayerIndex)
*pnLayerIndex = nLayer;
if (pnDataPlotIndex)
*pnDataPlotIndex = nDPIndex;
return TRUE;
}
++nLayer;
}
if (pnLayerIndex)
*pnLayerIndex = -1;
if (pnDataPlotIndex)
*pnDataPlotIndex = -1;
return FALSE;
}
// Search the layer where both two curves are both plotted
//glayerFound is layer where cuv2 is currently plotted
bool curve_both_in_layer(const curvebase& cuv1, const curvebase& cuv2, GraphLayer& glayerFound)
{
//----
// starting layer given, then we should not search if cuv2 already in that layer and
// we can assume this is the layer we want
if(glayerFound && curve_in_layer_get_index(cuv2, glayerFound) >= 0)
return curve_in_layer_get_index(cuv1, glayerFound) < 0? false:true;
//----
foreach (GraphPage pg in Project.GraphPages)
{
foreach(GraphLayer gl in pg.Layers)
{
int nCuv2 = curve_in_layer_get_index(cuv2, gl);
if(nCuv2 < 0)
continue;
glayerFound = gl;
int nCuv1 = curve_in_layer_get_index(cuv1, gl);
if(nCuv1 >= 0)
return true;
}
}
return false;
}
string curve_get_wks_col_names(curvebase& cc, string& strX, string& strY)
{
string strTemp;
string strWks;
strY.Empty();
strX.Empty();
if(cc)
{
cc.GetName(strTemp);
int nn = strTemp.Find('_');
if(nn > 0)
strWks = strTemp.Left(nn);
Worksheet wks(strWks);
if(!wks)
{
strWks.Empty();
return strWks;
}
strY = strTemp.Mid(nn+1);
if(cc.HasX(strTemp))
{
nn = strTemp.Find('_');
strX = strTemp.Mid(nn+1);
}
}
return strWks;
}
static bool check_set_col_analysis(Column& cc, bool bSetAsY = true)
{
int nFormat = cc.GetFormat();
if(bSetAsY && cc.GetType() != OKDATAOBJ_DESIGNATION_Y)
cc.SetType(OKDATAOBJ_DESIGNATION_Y);
if(nFormat != OKCOLTYPE_NUMERIC && nFormat != OKCOLTYPE_TEXT_NUMERIC)
{
cc.SetFormat(OKCOLTYPE_NUMERIC);
return true;
}
return false;
}
/** >Analysis
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
Return:
NULL if no active graph layer with active curve found, or if the operation failed
*/
curvebase& curve_duplicate_active(LPCSTR lpcszNewColName , bool bReuseIfInWks) //= NULL, = false
{
GraphPage gpg = Project.Pages();
string strNewCol = lpcszNewColName;
if(strNewCol.IsEmpty())
strNewCol = "A";
if(gpg)
{
GraphLayer glyr = Project.ActiveLayer();
if(glyr)
{
string strY, strX;
string strWks = curve_get_wks_col_names(Project.ActiveCurveBase(), strX, strY);
if(!strWks.IsEmpty())
{
Worksheet wks(strWks);
Column cx = wks.Columns(strX);
Column cy = wks.Columns(strY);
Column cNew = wks.Columns(strNewCol);
if(!bReuseIfInWks || !cNew.IsValid())
{
string strTemp;
wks.InsertCol(cy.GetIndex()+1, strNewCol, strTemp);
strNewCol = strTemp;
cNew = wks.Columns(strNewCol);
}
// we need to make sure new col is a Y col
check_set_col_analysis(cNew);
cNew.SetUpperBound(cy.GetUpperBound());
return wks.GetCurve(cx.GetIndex(), cNew.GetIndex());
}
}
}
return NULL;
}
bool add_curve_to_graph_layer(curvebase& cuv, GraphLayer &grl, int nColor, bool bRescale, int nPlotType)
{
int nPlot = grl.AddPlot(cuv, nPlotType);
DataPlot dp = grl.DataPlots(nPlot);
dp.SetColor(nColor);
if( bRescale )
grl.Rescale();
return true;
}
/**
*/
bool curve_update_in_page(curvebase& cuv, int nColor, GraphPage &gpg, bool bRescale)
{
if (!curve_in_page_get_indices(cuv, gpg)) // not present
{
GraphLayer grl = gpg.Layers(0);
if (!grl)
return false;
return add_curve_to_graph_layer(cuv, grl, nColor, bRescale);
}
else
gpg.Refresh();
return true;
}
// find the input curve layer and plot the result curve
bool curve_update(curvebase& cuvFit, const curvebase& cuvInput, const TreeNode& trInput, int nColor, bool bRescale) // bRescale = false
{
GraphLayer gl = get_graph_layer(trInput);
if(!curve_both_in_layer(cuvFit, cuvInput, gl) && gl) // there maybe many, we will just use 1st for now
{
/*
// cuvInput 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(nColor);
if( bRescale )
gl.Rescale();
*/
return add_curve_to_graph_layer(cuvFit, gl, nColor, bRescale);
}
return false;
}
/**
*/
int convert_regular_xyz_to_matrix(vector& vecX, vector& vecY, vector& vecZ, matrix& matData, double& dXmin, double& dXmax, double& dYmin, double& dYmax, bool bCheckData)
{
bool bRet;
int ii, jj, id, isize, iXStepLoc, iXNumSteps, iYStepLoc, iYNumSteps, iRet;
double dev, dXStep, dYStep;
// Check if X,Y,Z vectors are of equal length - return if not
int iXsize = vecX.GetSize();
int iYsize = vecY.GetSize();
int iZsize = vecZ.GetSize();
if(iXsize < 4) return 1; // support only matrix size of greater than 2x2
if( (iXsize != iYsize) || (iYsize != iZsize) || (iZsize != iXsize) ) return 1;
// Create a temporary worksheet, and fill in the vectors into first three columns
Worksheet wksTemp;
bRet = wksTemp.Create("Origin.otw", CREATE_TEMP);
string strWksName;
wksTemp.GetPage().GetName(strWksName);
wksTemp.DeleteCol(0);
wksTemp.DeleteCol(0);
wksTemp.AddCol();
wksTemp.AddCol();
wksTemp.AddCol();
Dataset dsX(wksTemp, 0);
Dataset dsY(wksTemp, 1);
Dataset dsZ(wksTemp, 2);
dsX = vecX;
dsY = vecY;
dsZ = vecZ;
// Create two more columns in temp worksheet for computing x/y step values
wksTemp.AddCol();
wksTemp.AddCol();
Dataset dsXMed(wksTemp, 3);
Dataset dsYMed(wksTemp, 4);
// Find step location, number of steps, and step value for x data
iRet = convert_regular_find_step(0, wksTemp, iXStepLoc, iXNumSteps, dXStep);
if(iRet != 0) return 2;
// Find step location, number of steps, and step value for y data
iRet = convert_regular_find_step(1, wksTemp, iYStepLoc, iYNumSteps, dYStep);
if(iRet != 0) return 2;
// Do a check on whether the x and y data groups agree
// Number of groups in one should match group length in the other
if ( (iXStepLoc != iYNumSteps) | (iYStepLoc != iXNumSteps) ) return 3;
// If data should be checked for iregularity, then...
if(bCheckData)
{
// Check for x data for deviations
iRet = convert_regular_check_data(0, wksTemp, iXStepLoc, iXNumSteps, dXStep);
if(iRet != 0) return 4;
// Check for y data for deviations
iRet = convert_regular_check_data(1, wksTemp, iYStepLoc, iYNumSteps, dYStep);
if(iRet != 0) return 4;
}
// Now sort the worksheet wrt Y ascending as primary and and
// X ascending as secondary - this format is needed to copy to matrix
using sort = LabTalk.sort;
sort.wksname$ = strWksName;
sort.c1 = 1; // sort only first 3 cols
sort.c2 = 3;
sort.r1 = 1;
sort.r2 = isize;
sort.cname1$ = "A: B";
sort.cname2$ = "A: A";
sort.wks();
// Now fill matrix with Z data, and return coordinate values in variables passed
matData.SetSize(iXStepLoc, iYStepLoc);
// Get min. max values for use in setting matrix co-ordinates
dXmin = min(dsX);
dXmax = max(dsX);
dYmin = min(dsY);
dYmax = max(dsY);
// Fill matrix by just using Z dataset
matData.SetByVector(dsZ);
// Success
return 0;
}
/**
*/
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, double dQIL, double dWFL)
{
int i, j, m, n, nx, ny, iRet, iErr = 0;
double xlo, xhi, ylo, yhi;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -