Origin Cに引数を渡す
目次
概要
LabTalkとOriginCの間で作業する場合、コードで変数を渡す必要がある場合があります。LabTalkでは、数値変数(int、doubleなど)、文字列変数、および列レベルの範囲変数を直接渡すことができます。他のLabTalkオブジェクト(ワークシート範囲、グラフページ範囲など) は文字列で渡され、Origin C関数内でこれらの文字列を操作する必要があります。次の表は、LabTalkからOrigin Cに値を渡すときに関数の引数を処理する方法をまとめたものです。
| LabTalkのデータ型 | Origin C の引数 | 参照渡しをサポート |
|---|---|---|
| double | double | 可 |
| int | int | 可 |
| string | string | 可 |
| column level range | DataRange | 不可 |
| range | string | 不可 |
| string registers | string | 不可 |
| loose dataset | vector | 不可 |
| string array | vector<string> | 不可 |
| tree | Tree | 可 |
以下のサンプルでさまざまなケースへ対処法を紹介しています。
サンプル
int型を値で渡す
このサンプルでは、Xインデックス番号に基づいて曲線に作用するトレース補間を行い、データの連続的な面を保持して補間します。サンプルでは、Origin CとLabTalkの組み合わせて使用します。曲線の次数を表す整数n が、LabTalkでOrigin Cに渡されます。
Origin C コード:
#include <origin.h> #define aa 0.5 void main_Data(int n) { vector<double> x={0}, y={0}; hilbert_2D(n, x, y); Worksheet wks=Project.ActiveLayer(); if (wks){ Dataset c1(wks,0); Dataset c2(wks,1); c1=x; c2=y; } } void hilbert_2D(int n, vector<double> &x, vector<double> &y) //ヒルベルト曲線を作成 { vector x0 = {0}, y0 = {0}; while(n-->0){ x0=x; y0=y; x.RemoveAll(); y.RemoveAll(); x.Append(aa*(-aa+y0)); x.Append(aa*(-aa+x0)); x.Append(aa*(aa+x0)); x.Append(aa*(aa-y0)); y.Append(aa*(-aa+x0)); y.Append(aa*(aa+y0)); y.Append(aa*(aa+y0)); y.Append(aa*(-aa-x0)); } }
LabTalkスクリプト:
newbook name:="Trace_Interp"; main_Data(4); // 4次のヒルベルト曲線 interp1trace -r 2 iy:=[Trace_Interp]1!(A,B) method:=spline; //スプライン法でトレース補間. plotxy iy:=((1,2),(3,4)) plot:=200; set %C -w 1500; // 線の太さを設定
double型を値で渡す
double、int、string変数をOrigin C関数に直接渡すことができます。
Origin C コード:
#include <origin.h> double GetLarger(double a, double b) { return a>b?a:b; }
LabTalkスクリプト:
double a = 3.5, b = 8.9; double c = GetLarger(a, b); ty "The larger value is $(c)";
整数を参照で渡す
double、int、string型などは参照で渡すこともできます。
Origin C コード:
LabTalkスクリプト:
int a = 10, b = 20; ty "First, a = $(a), and b = $(b)"; MySwap(a, b); ty "Then, a = $(a), and b = $(b)";
文字列を参照で渡す
文字列変数はOrigin C関数に直接渡すことができ、参照でも渡せます。
Origin C コード:
#include <origin.h> int CheckFile(string& strFile, string& strExt) { int nRet = strFile.IsFile(); if(nRet != 0) { separate_file_name_ext(strFile, NULL, &strExt); strFile = GetFileName(strFile, TRUE); } return nRet; }
LabTalkスクリプト:
string strFile$ = %Y; strFile$ =strFile$+"origin.ini"; string strExt; CheckFile(strFile$, strExt$); ty "strFile=%(strFile$), strExt=%(strExt$)"
文字列配列を渡す
vector を使用して、Origin C内で文字列配列またはルースデータセットのコピーを作成できます。
Origin C コード:
#include <origin.h> void TyMyLove(vector<string> strA) { int nSize = strA.GetSize(); for(int i=0; i<nSize; i++) { printf("I Love %s!\n", strA[i]); } }
LabTalkスクリプト:
stringarray aa; aa.Add("Boston"); aa.Add("New York"); aa.Add("Los Angeles"); TyMyLove(aa);
列範囲を渡す
列範囲変数は直接渡せます。
以下のサンプルで、列変数をOrigin Cに渡す方法を示しています。
必要なOriginのバージョン: 9.0 SR1以降
Origin C コード:
#include <origin.h> double MyMean(DataRange dr) { double dMean; int nN; vector vec; dr.GetData(&vec, 0); int nRet = ocmath_basic_summary_stats(vec.GetSize(), vec, &nN, &dMean); if(0 == nRet) return dMean; return NANUM; }
LabTalkスクリプト:
newbook; col(1) = data(0, 100); range rr = [%H]1!1; double Rmean=MyMean(rr); ty "The Mean of %(rr) is $(Rmean)";
Note:
|
ワークシート範囲を渡す
ワークシート範囲を渡す場合、%()表記を使用してワークシート範囲名を渡すか、文字列変数を文字列としてOrigin C関数に渡すことができます。Origin C 関数内では、okxf_resolve_string_get_origin_object()関数 (xfutils.hを含める) によって文字列を適切なオブジェクトにするか、文字列から適切なオブジェクトを作成することもできます。
LabTalkスクリプトで範囲名を引用するか、文字列変数を直接使用して、文字列を明示的に渡す必要があります。
Origin C コード:
#include <Origin.h> #include <xfutils.h> int MyCopyWks(string strSource, string strTarget) { Worksheet sWks, tWks; int nRet = okxf_resolve_string_get_origin_object(strSource, &sWks); nRet *= okxf_resolve_string_get_origin_object(strTarget, &tWks); if( !nRet ) { printf("Worksheet name is wrong!\n"); return 0; } sWks.CopyTo(tWks, 0, -1, 0, -1, 0); return 1; }
LabTalkスクリプト:
range ra = [book1]sheet1!; range rb = [book2]sheet1!; int nRet = MyCopyWks("%(ra)", "%(rb)");
作図範囲を渡す
ワークシート範囲の操作と同様に、プロット範囲を文字列としてOrigin Cに渡すこともできます。
LabTalkとOrigin C間でやり取りする場合、開始インデックスが異なることに注意してください。
Origin C コード:
#include <Origin.h> #include <xfutils.h> int ChangeDPColor(string strDP, int nColor) { DataPlot dp; int nRet = okxf_resolve_string_get_origin_object(strDP, &dp); if( !nRet ) { printf("Not a valid data plot!\n"); return 0; } if( nColor < 1 || nColor > 24 ) { printf("LabTalk color number sould be 1 ~ 24!\n"); } // Origin Cの色インデックスは0から開始 nColor--; dp.SetColor(nColor, TRUE); return 1; }
LabTalkスクリプト:
newbook; col(1) = data(1, 10); col(2) = col(1); white_noise 2; plotxy 2 202; Range dp = [%H]1!1; string strDP$ = %(dp); int nC = color(green); int nRet = ChangeDPColor(strDP$, nC);
ウィンドウ名を渡す
ウィンドウ名をOrigin C関数に直接渡すことができます。適切なオブジェクトコンストラクターがあれば、Origin Cで対応するオブジェクトを作成できます。
Origin C コード:
#include <Origin.h> int GetPlotsNum(string pName) { int nPlots = 0; GraphPage gp(pName); if( !gp.IsValid() ) { printf("Not a valid page!\n"); return 0; } foreach( GraphLayer gl in gp.Layers ) { foreach( DataPlot dp in gl.DataPlots ) nPlots++; } return nPlots; }
LabTalkスクリプト:
newbook; string fname$ = system.path.program$; fname$ += "Samples\Curve Fitting\Exponential Decay.dat"; impasc; worksheet -s 0 0 -1 -1; worksheet -p 201; int nPlots = GetPlotsNum("%H"); ty "There are $(nPlots) plots in %H";
ツリーを渡す
ツリーをOrigin Cに直接渡すことができます。
Origin C コード:
#pragma labtalk(4) int tt(Tree& tr, string strAppsPath) { Tree tr1; if(!tr1.Load(strAppsPath)) return 1; tr.Replace(tr1, TRUE, TRUE); return 0; } #pragma labtalk(0)
LabTalkスクリプト:
Tree tr1; string strApps$="%@AOpxList.xml"; if(0==tt(tr1,strApps$)) tr1.=;
LabTalkツリーをXMLで構成する
LabTalkツリーをXMLで構成できます。
XML用のOrigin C コード:
string st(string strAppsPath) { string str; Tree tr; if(tr.Load(strAppsPath)) { tr.GetString(str); return str; } }
LabTalkスクリプト:
string strApps$="%@AOpxList.xml"; string strXML$ = st(strApps$)$; Tree tr1 = strXML$; tr1.=
これはデータコネクタで使用できます。例えば、CSVファイルをインポート後以下のスクリプトを実行するとインポートダイアログ設定を取得できます。
Tree tr1=wks.dc.optn$; tr1.=;
また、その逆もサポートされています。
string str$ = wks.dc.optn$; Tree tr1 = str$; tr1.=;
文字列で範囲を返す
ほとんどのOrigin CオブジェクトはLabTalkに返せません。したがって、rangeを返したい場合は、GetRangeString() メソッドを使用して範囲文字列をLabTalkに返すことができます。
Origin C コード:
#include <origin.h> #include <xfutils.h> // この関数は、strWksNameのデータを使用してレイヤstrGLに3D散布図を挿入 int Insert3DScatter(string strGL, string strWksName) { // 名前でグラフレイヤオブジェクトを取得 GraphLayer gl; if( !okxf_resolve_string_get_origin_object(strGL, &gl) ) { out_str("Invalid graph layer!"); return 0; } // 名前でワークシートを作成 Worksheet wks(strWksName); DataRange dr; int nR = 0; dr.Add("X", wks, 0, 0, -1, 0); dr.Add("Y", wks, 0, 1, -1, 1); nR = dr.Add("Z", wks, 0, 2, -1, 2); // 3D散布図を追加 int nPlot = gl.AddPlot(dr, ID_3D_GRAPH_SCATTER); if( nPlot == -1 ) { out_str("Cannot add plot!"); return 0; } DataPlot dp = gl.DataPlots(nPlot); Tree tr; tr = dp.GetFormat(FPB_ALL, FOB_ALL, TRUE, TRUE); tr.Root.Symbol.Shape.nVal = 11; tr.Root.Symbol.Interior.nVal = 8; tr.Root.Symbol.EdgeColor.nVal = 15; tr.Root.DropLines.Z.nVal = 0; if( !dp.ApplyFormat(tr, TRUE, TRUE) ) { out_str("Apply format failed!"); return 0 } return 1; } // この関数は透明なメッシュ グラフを作成 // グラフレイヤ名strGLNameは参照によって渡され、 // LabTalk でこの変数を再利用可能 int CreateMeshPlot(string strMOName, string& strGLName) { // 行列オブジェクトを名前で取得 MatrixObject mo(strMOName); okxf_resolve_string_get_origin_object(strMOName, &mo); GraphPage gp; gp.Create("mesh"); GraphLayer gl = gp.Layers(); // レイヤにメッシュプロットを追加 int nPlot = gl.AddPlot(mo, IDM_PLOT_3D_MESH); if( nPlot < 0 ) { out_str("Cannot create 3D mesh!"); return 0; } // プロットを微調整 DataPlot dp = gl.DataPlots(nPlot); Tree tr; tr = dp.GetFormat(FPB_ALL, FOB_ALL, TRUE, TRUE); tr.Root.Grids.FrontColor.nVal = 8; tr.Root.Grids.BackColor.nVal = 8; tr.Root.Grids.Width.dVal = 0.8; tr.Root.Grids.Color.dVal = 19; tr.Root.Grids.Transparency.nVal = 70; if( !dp.ApplyFormat(tr, TRUE, TRUE) ) { out_str("Apply format failed!"); return 0 } // グラフレイヤの範囲文字列を返す gl.GetRangeString(strGLName); gl.Rescale(); return 1; }
LabTalkスクリプト:
newbook; string fname$ = system.path.program$; fname$ += "Samples\Matrix Conversion and Gridding\XYZ Random Gaussian.dat"; impasc; range rw = [%H]1!3; rw.type = 6; xyz_renka iz:=rw rows:=20 cols:=20; range rm = [%H]1!1; // 範囲を文字列として渡し、文字列変数を参照で渡す string strGLName$; CreateMeshPlot("%(rm)", strGLName$); // 2秒待つ sec -p 3; string strWksName$ = rw.GetLayer()$; // レイヤ名、ワークシート名を文字列として渡す Insert3DScatter(strGLName$, strWksName$);
