ホーム 研究発表 履歴 その他

Igorメモ

データ解析ソフトウェア Igor の簡単な使い方の覚書です.

keywords:
エラーバー 行列 フィッティング(回帰分析,新規関数) ウェーブ統計 データ読み込み
コメントアウト duplicateのエラー抑制 各waveを自動で異なる色に グラフを自動で閉じる
三次元プロット 短時間FFT タイマー(マクロ)

よく忘れる事:
if文の書式 wave(0,1)とweve[0,1]の違い フィッティングのマスク 数字と文字列の結合
変数で表したウェーブ同士の演算 マクロ中の変数をグラフのcaptionに入れる書式

全体の目次:
1. Igorとは

2. 基本的な使い方
  2.1. waveの作成と取り扱い
    2.1.1. ウェーブの作成例(外部テキストファイルの読み込みを含む)
    2.1.2. wave同士の算術演算とwave中のポイントの扱い
    2.1.3. 行列ウェーブ等,2次元以上の場合
  2.2. グラフプロット
    2.2.1. 基本的な使い方とx-yプロット
    2.2.2. 三次元プロット
  2.3. 記述統計(平均値,最大最少など)
  2.4. フィッティング

3. Igorマクロの例
  3.1. なぜマクロか
  3.2. 簡単なマクロの使い方
  3.3. マクロの作成方法と動かし方
  3.4. 書式の約束ごと
  3.5. その他のコツなど(改行,Proc,組み込み関数等)
  3.6. Igorマクロの使用例
    1. テキスト形式のデータを連続ロード
    2. グラフのwindowを順にactivateする
    3. グラフのwindowを順に閉じる
    4. waveのn1〜n2の行に"nan"を書き込む
    5. 一定時間ごとの自動処理
    6. 横河電機WE7000のバイナリデータの連続ロード
    7. 組み込み関数を使用した短時間FFTで周波数スペクトルを作成
    8. データポイントを間引く

Igor Pro 6.22Jで動作確認

1. Igorとは
IGOR ProはWaveMetrics社のデータ解析ツールです. エクセル等では扱えないような大量の数値データの処理が可能で,自由度の高いグラフ作成や実験データ解析に適しています. データの統計処理や関数によるフィッティング,微分積分やFFT等の組み込み関数が豊富に用意されている他,ユーザー定義により機能を拡張する事も出来ます. また,GUIからのメニュー操作の大半をコマンドラインからも実行可能で,メニュー操作の履歴はコマンド窓に記録されます.このため,煩雑になりがちな繰り返し操作をコマンドラインに連続して打ち込んだり,簡単なマクロを使用したデータ処理の自動化が容易です. 内容に一切の責任は負えませんが,以下は簡単な使い方についてのメモです.


2. 基本的な使い方
2-1. waveの作成と取り扱い

       

2-1-1. ウェーブの作成例(Igor内での作成と外部テキストファイルの読み込み)

  • Igorでは,データはwaveに入れて扱います.
  • waveは,tableで開いて数値を確認したり,グラフ化して目視する事が出来ます.
  • 「データ」−「ウェーブを作成」から,任意の行数(データ点の数)と1-4の次元のwaveを作成出来ます.

  • コマンドラインで edit と入力すると,tableが一つ開きます.
  • 入力可能なマス目に適当な数字を入れると,wave0等という名前のwaveが作成されます.
  • waveの行数は,数字を追加するか,右クリック−再定義からも変更が可能です.
  • 「x」はポイント位置を示す数を表し,例えばwave0=10*xで一次関数が作成されます.
  • データ無しや不明の箇所は,nanを入力するとそのように扱われます.
  • waveの全値を2倍: wave0*=2.0 等のようにまとめて処理可能です.

  • waveは,オシロ等のデータを読み込んで作る事も出来ます.
  • 「データ」−「ウェーブをロード」−「一般テキストをロード」でテキストファイルを読み込みます.
  • テキストファイルによっては,ファイルのアイコンをIgor画面に放り込めばロードされます.
  • 多数のデータファイルのロードは,マクロの使用が効率的です(マクロの項で後述).


    2-1-2. wave同士の算術演算とwave中のポイントの扱い
    (これらは,コマンドウインドウからの入力例です.// 以降はコメント)

      Make/N=100/D/O w1,w2,w3; Edit w1,w2,w3; // wave3つ作成,編集 (D:倍精度,O:上書き許可)
      w1=x // w1に0,1,2...という数字データを入力
      w2=w1*100; w3=1/(w1+1); // wave同士の操作
      Display w2 vs w1; Display w3 vs w1; // ついでにグラフ表示

      print w3[5]; // 「ウェーブw3のn番目のポイントの値」は,w3[n]と表す

    2-1-3. 行列ウェーブ(等,2次元以上)の場合

    → グラフの作成方法は,三次元プロット

    1次元の場合と同様ですが,ウェーブの次数が異なる時(例えば,行列の特定の行や列を
    1次元ウェーブとして取り出す等)は,例のようにp,q,r,sを使用します.
    ウェーブ間で行数が異なる時も注意が必要です.配列の宣言で大きさ不足の時の
    ような動作をする事があります.
    行列について,Igorマニュアルの Multidimensional Wave Assignment に詳細な情報があります.

      Make/N=(3,5)/D/O wm; Edit wm; // 3x5の行列を作成しテーブルに表示
      wm[2][3]=10 // 行列wmの(2,3)の位置に数値10を入力
      wm=0 // 行列wmの全てのマスに0を入力
      wm[1][]=1 // 行列wmの「行」が1のマス全てに1を入力
      wm[][3]=2 // 行列wmの「列」が3のマス全てに2を入力

      Make/N=5/D/O w; Edit w; // テスト用に1次元waveを作っておく
      wm=x*10+y // 行列に適当な数を入力しておく
      w=wm[1][p] // 行列wmの行1を1次元wave「w」に入力(横1列を縦に)
      w=wm[p][2] // 行列wmの列2を1次元wave「w」に入力(縦1列を縦に)
      wm[1][]=w[q] // 1次元wave「w」を行列wmの行1に入力(縦を横1列に)
      wm[][2]=w[p] // 1次元wave「w」を行列wmの列2に入力(縦を縦1列に)



    2-2. グラフプロット
    2-2-1. 基本的な使い方とx-yプロット

           

    グラフ作成
  • 「ウインドウ」−「グラフ表示」で,適当なwaveを選択するとグラフが表示されます.
  • YウェーブはCtrlキーで複数選択可能です.
  • グラフを作成した後に,「グラフ」-「グラフにトレースを追加」でも別waveを追加出来ます.
  • トレース追加の際,「軸」で異なるスケールの左右上下の軸を作成可能です.

    ウェーブのスケーリング
  • Xウェーブを選択しない時,規定値では,横軸はYウェーブのポイント数になっています.
  • これを変更するには,横軸に例えば時間軸等のwaveを指定するか,次項のsetscaleを使用します.
  • 「データ」−「ウェーブスケーリングを変更」から,waveのステップ間隔と単位を設定出来ます.
  • 「解析」メニューの微分積分やフーリエ変換を行う時には,スケールの設定が有効です.

    軸と外見の設定
  • 軸をダブルクリックするか,または「グラフ」−「軸…」を選択して,軸ラベルや範囲の設定をします.
  • 設定は,選択した軸(縦,横,複数選択も可能)に反映されます.
  • グラフ表示範囲の指定は,グラフ上で左クリック&ドラッグでも可能です(Ctrl-aで解除).
  • データ点をクリックすると,マーカーや折れ線の変更が出来ます.

    エラーバー
  • グラフ(トレース)をダブルクリック->「エラーバー」ボックスにチェックを入れる.
  • 各データ点の標準偏差なりのウェーブをあらかじめ作っておき,「ウェーブの+/-」で選択.等とする.

    ショートカット
  • Ctrl-a: 軸範囲が自動設定に戻り,全てのデータ点が表示されます.
  • Ctrl-i: カーソル表示.
  • Ctrl-t: ドローツールが選択出来,グラフ上に文字や線を記入出来ます.
  • Ctrl-z: 最新のグラフ操作を取り消します.
  • Ctrl-d: グラフを複製します.
  • Ctrl-w: ウィンドウを削除.
  • Ctrl-j: コマンドウィンドウに切り替え.

    グラフ設定
  • 「グラフ」−「グラフ設定を保存」から,設定した軸や複数waveの色を規定値にする事が出来ます.
  • デフォルトではwaveの色は全て赤で,waveを追加した後に手作業で色を変更する事が多いです.
      これを変更して自動でカラフルなグラフを作るには,次のようにします:
      まず,以下をコマンドラインから入力します(コピーペーストしてEnterキーでOK).

      Make/N=2/D/O w1; w1=1; Duplicate/O w1 w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12;
      w2[1]=2;w3[1]=3;w4[1]=4;w5[1]=5;w6[1]=6;w7[1]=7;w8[1]=8;w9[1]=9;w10[1]=10;w11[1]=11;w12[1]=12;
      Display w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12;
      ModifyGraph rgb(w2)=(0,12800,52224),rgb(w3)=(0,39168,0),rgb(w4)=(65280,21760,0);
      ModifyGraph rgb(w5)=(52224,34816,0),rgb(w6)=(52224,52224,0),rgb(w7)=(16384,65280,16384);
      ModifyGraph rgb(w8)=(0,52224,52224),rgb(w9)=(0,34816,52224),rgb(w10)=(16384,28160,65280);
      ModifyGraph rgb(w11)=(29440,0,58880),rgb(w12)=(52224,0,41728);

      次に,「グラフ」−「グラフ設定を保存」の「XYプロット: ウェーブスタイル(〜)」に
      チェックを入れて,「設定を保存」を押します.次回からのグラフ作成に反映されるはずです.

      色はお好みで変更して下さい.グラフのwaveをダブルクリックすると色が選べ,
      コマンドラインに色指定の番号が履歴として表示されます.

    2-2-2. 三次元プロット

    Igorで可能なx-y-zプロットの種類(の一部)
  • 等高線プロットや3dプロットが可能です.
  • 以下では例として格子点状のデータを扱いますが,非格子点状のデータでもプロット可能です.

                     

    「xy座標の平面上でz(x,y)という量を等高線プロットする」手順
  • 行列ウェーブか,またはx,y,zの3つの1次元ウェーブかを用意します(行列の方が高速).
  • ウィンドウ→新規→等高線プロットを選択し,
           行列ウェーブなら: 「z値のマトリックス」で,zウェーブとして行列を選択します.
           3つの1次元ウェーブなら: 「x,y,zのウェーブ」で,それぞれのウェーブを選択します.
  • グラフ→等高線アピアランスを修正 から,色々変更出来ます.

  • サンプルの行列データを作り,コマンドラインから等高線プロットを行う具体例です.

      Make/N=(100,100)/D/O wm; Edit wm // 100×100の行列を作る
      wm=sin(x*0.1)+0.5*cos(y*0.2) // 適当な値を作成
      Display;AppendMatrixContour wm // 等高線プロット
      SetScale/P x 0,0.01,"m", wm; SetScale/P y 0,0.01,"m" // x,yのスケール調整

  • 1次元ウェーブの場合は,以下のようなx,y,z 3つのウェーブを作り,上記の操作をします.
      x y z
      1 1 z11
      1 2 z12
      1 3 z13
      2 1 z21
      2 2 z22
      2 3 z23
      3 1 z31
      3 2 z32
      3 3 z33

  • 上の行列の場合と同じ事を1次元ウェーブで行う例です(処理に時間が掛かります).

      Make/N=10000/D wx,wy,wz; Edit wx,wy,wz; // 10000ポイントのwaveを3つ作る
      wx=trunc(x/100); wy=x-100*trunc(x/100); wz=sin(wx*0.1)+0.5*cos(wy*0.2)
      Display;AppendXYZContour wz vs {wx,wy}

  • ラインの等高線の他に,Igorマクロを使用してイメージコンタを作成出来ます.
      AppendImageToContourをIgorに読み込み,コンパイルします.
      次に,等高線グラフを選択した状態でマクロを選択し,等高線と諧調数を指定します.
      グラフ→イメージアピアランスを修正 から,色々変更出来ます.

  • ウィンドウ→新規→3D plotsから,Surface plotが作成出来ます.


    2-3. 記述統計(平均値,最大最少など)

  • 「解析」−「記述統計」から,データの最大最小や平均値を評価します.
  • waveの特定の領域を対象にする時は,[]でポイント,()でscaleを反映した指定が出来ます.
  • scaleを反映した範囲指定は,コマンドラインの方が使い勝手が良いです(「コマンドライン」ボタン).
  • 解析結果はV_avg等に入っているので,コマンドラインで print V_avg 等で最新の値が表示されます.

      Make/N=1000/D/O w; w=cos(x/10)+1; Display w; // テスト用wave作成
      WaveStats w // wave「w」の統計情報
      WaveStats/Q w; print V_avg // 平均値のみ表示
      WaveStats/R=[510,520] w // ポイント510-520の範囲の統計
      WaveStats/R=[510,] w // ポイント510以降の範囲の統計
      WaveStats/R=[pcsr(A),pcsr(B)] w // Ctrl-Iで表示しdrag&dropしたカーソル範囲の統計


    2-4. フィッティング

    基本操作
  • 対象ウェーブのグラフを作成し,「解析」−「回帰分析」を選択します.
  • 適当な「関数」と「Yデータ」を選択して,「実行」を押します.
  • フィッティング結果は,W_coefというウェーブ等に書き込まれます.

      Make/N=5/D/O w1; Display w1; ModifyGraph mode=3; w1=x+0.3*sin(x*10); // テスト用wave作成
      CurveFit/NTHR=0 line w1 /D // y=a*x+bでフィッティング(「回帰分析」メニューからの操作と同じ)
      Edit W_coef // フィッティング結果を確認

    係数の一部を固定したフィッティング

  • 特定の係数を固定してフィッティングを行う時は,「係数」タブを使用します.
  • 「保持?」ボタンをクリックして,「初期推定値」を入力してから「実行」を押します.
  • 例えば指数関数(exp)には,規定値で定数項y_0が入っていますので注意が必要です.

    データの特定の範囲だけをフィッティング
  • 特定の範囲だけフィッティングを掛けるには,「データオプション」タブを使用します.
  • 「範囲」に開始と終了ポイントを入力するか,カーソル(Ctrl-I)により範囲を指定します.

  • より細かく範囲を設定するには,「データオプション」の「データのマスク」を使用します.
  • マスクwaveは,フィッティング対象waveと同じ長さで,1(使用)か0(除外)を入力します.
  • 「関数とデータ」タブのYデータにw1,「データオプション」タブのデータのマスクにmaskを選択します.
  • w1の2行目と3行目を無視してフィッティングを行う例は以下の通りです.

      Make/N=5/D/O mask; mask=1; mask[2]=0; mask[3]=0; Edit mask; // マスク用wave作成
      CurveFit/NTHR=0 line w1 /M=mask /D // [2][3]は除外してフィッティング

    回帰関数を自分で作る
  • 以下は,a*x^2+b*x+c という関数を作ってデータフィッティングを行う例です.
  • 「解析」−「回帰分析」の「新規回帰関数」を押します.
  • 「回帰関数名」にftest,「回帰係数」にa,b,cの3つ(改行して),「独立変数」にxを入力します.
  • 「回帰式」に f(x) = a*x^2+b*x+c と入力し,「回帰関数の保存」を押します.
  • 関数がftestである事を確認し,「係数」タブの「初期推定値」に全て1(適当で良い)を入力します.
  • ウェーブ(下で作成するw2)を選択し「実行」を押すと,フィッティングで係数値3,2,1をが再現されます.

      Make/N=10/D/O w2; Display w2; ModifyGraph mode=3; w2=3*x^2+2*x+1; // テスト用wave作成
      FuncFit/NTHR=0 ftest W_coef w2 /D // フィッティングの実行


    3. Igorマクロの例
    3-1. なぜマクロか
    マクロを利用すると,ルーチン作業(例:多数のファイルからデータを読み込む,類似処理を多数のデータに施す,一般的なウィンドウ操作,データのオフセットやゲインの調整,グラフ作成,統計やフーリエ変換等の処理,グラフのレイアウト表示や印刷等)や複数の処理等を自動化して効率よく作業が行えます.



    3-2. 簡単なマクロの使い方
    Igor上で,ウィンドウ-プロシージャウィンドウ-プロシージャウィンドウを選択します.
    Procedureと書かれたウィンドウが現れるので,以下のテキストを追加します.

    Macro test1()
    print "macro test"
    EndMacro

    プロシージャウィンドウの下にある「コンパイル」ボタンを押し,メニューバーの「マクロ」をクリックすると,「test1」というマクロが作成されています.「test1」を選択すると実行され,コマンドウィンドウに macro test と表示されるはずです.




    3-3. マクロの作成方法と動かし方
    Igorでは,3-2のように,テキストをプロシージャウインドウに記述する事でマクロを作成します.また,Igorは拡張子が.ipfのテキストファイルをマクロとして認識します.保存(ファイル-プロシージャのコピーを保存)されたマクロファイルのアイコンをエクスペリメントファイル上に放り込むと,マクロとして認識されます.

    マクロを動作させるには,3-2のようにメニューから選択する他に,コマンドラインに test1() のように入力してもOKです.

    一つのマクロファイルには,異なる名前の複数のマクロを記述する事が出来ます.
    従って,以下のマクロ例を,次々とプロシージャファイルに追加して大丈夫です.



    3-4. 書式の約束ごと
    マクロの最初と最後
    マクロは,マクロ名を宣言する Macro **** 行から始まり,EndMacro の行で終了します.

    コメントアウト
    // 以降,改行までマクロに無視されます.
    日本語の倍角文字が//の直後に続くとエラーとなるため,//の前後には半角スペースを
    入れた方が無難です.

    マクロの高速化
    次項の変数宣言の後に
    silent 1; pauseupdate;
    と書く事で,マクロ実行中のコマンドライン表示とグラフとテーブルの再描写が抑制され,
    高速動作するようになります.

    文字変数と数字変数
    数字と文字の変数は,最初にそれぞれ variable と string で宣言してから使用します.
    最初のMacro行の後に空行があるとエラーが出ます.
    変数としての文字は""なし,文字通りの文字列は""でくくって扱います.
    Macro test2()
    variable n1;
    string name1;
    n1=1; name1="nametest";
    print n1,name1,"name1"; // "name1"はそのまま文字が表示される.
    EndMacro

    ウェーブの扱い
    マクロ中でウェーブを扱う時は,ウェーブ名の文字列の最初に$を付けます.
    また,変数を使って表したウェーブ同士の演算を行う時は,全体を()でくくります.
    Macro test3()
    string name1,name2,name3;
    Make/N=3/D/O w1,w2,w3;
    name1="w1";name2="w2";name3="w3";
    print name1; Display $name1;
    $name3=($name1)+($name2);
    EndMacro

    外部からの数字の入力(ファイル番号や処理の分岐等)
    変数として test(n1),test(n1,n2) 等としてカッコ内に variableを書いておくと,実行時
    に開くダイアログで数字の入力が可能です.コマンドウィンドウから,test4(1,10) のよう
    に直接数字を入力する事も出来ます.マクロ内で数字を具体的に記述した場合には,
    そちらが優先されダイアログは開きません.
    Macro test4(n1,n2)
    variable n1,n2;
    print n1,n2
    EndMacro

    文字の結合
    外部入力した数字と文字等を結合してファイル名等を作成するには, file1=name1+".txt"; などとします. 数字と文字同士は結合出来ないので,あらかじめ name1=num2str(n1); と数字変数を文字変数に変換して file1=name1+".txt"; とするか,または file1=num2str(n1)+".txt"; のようにします.
    例えば,TEK0001.csv という名前のデータファイルを変数を使って表すには "TEK000"+name1+".csv" となります.ファイル番号が9を超えてゼロが減る時は,後述のようにして扱う事が出来ます.
    Macro test5(n1)
    variable n1; string name1,file1;
    name1=num2str(n1);
    file1=name1+".txt";
    print file1;
    EndMacro

    if文の基本書式と大小記号
    Macro test6(n1)
    variable n1;
    if (n1<=0)
    print "run";
    else
    print "not run";
    endif
    EndMacro

    == equal
    != not-equal
    < less than
    <= less than or equal
    > greater than
    >= greater than or equal

    複数の条件
    if(a>1&&b==0)

    do-while文
    複数のファイル読み込みやグラフ描画等で使用します.
    Macro test7()
    variable n1,n2;
    n1=1; n2=3;
    do
    print "macro test",n1;
    n1+=1;
    while(n1<=n2)
    EndMacro


    3-5. その他のコツなど
    マクロ中の「;」
    改行の代わりに「;」と書くと行の終わりとして扱われます.一行に複数行文の記述が可能になり,縦のスペースの節約が出来ます.
    例: variable n1,n2; string name1,name2,name3,name4;

    MacroとProc
    Macroの代わりにProcを使うと,マクロメニューからは表示されなくなります.コマンドラインや別のマクロからの呼び出しは同様に使用する事が出来ます.
    マクロが多すぎると「マクロ」メニューから表示されなくなる問題は,使用頻度の低いmacroをprocに変更する事で回避出来ます.

    複数のMacroをまとめて動かすMacro
    マクロを組み合わせて使用時(例えば,データロード,ゲイン調整,グラフ表示,印刷等のマクロを別々に作成しておき,まとめて動作させるマクロを別に作る等)に使用します.変数の受け渡しも可能です.
    Macro test8(n1)
    variable n1;
    test5(n1);
    test6(n1);
    EndMacro

    MacroとFunction
    マクロは実行速度が速くありません.計算量の多いデータ解析をする時は,Functionとしてコンパイルさせた後に使用した方が遥かに実用的です.

    上書き指定によるエラーの抑制など
    マクロ中でファイルの複製作業を行うと,上書き防止のダイアログで処理が止まり,事前に消去が必要となり煩雑な事があります.
    Duplicate/O data2 $name0;
    のように /O オプションで上書き指定する事で回避出来ます.

    また,WaveStats のようにデフォルトでコマンドラインに多くの文字をprintするコマンドは,WaveStats/Q のように /Q オプションで出力を減らす事が出来ます.
    WaveStats/Q wave1; print V_avg

    print コマンド
    print は,FORTRAN の write(6,*) や C の printf と類似したコマンドです.コマンドラインやマクロ中で, print "test", 100 のようにコマンドラインに文字や数字や変数を出力する事が出来ます.マクロのバグ取り時に使用出来ます.

    組み込み関数のテスト
    printを使用した組み込み関数の動作例です.いずれもコマンドからの入力例と結果です.オプションなどの詳細は「リファレンス」に掲載されています.

    print 1+2*3+2^3, exp(1), ln(e), log(10), cos(60*pi/180), asin(0.5)*180/pi, mod(60,7) // 数学演算
      15 2.71828 1 1 0.5 30 4

    print Secs2Date(DateTime,0), Secs2Time(DateTime,3) // 日付と時刻の取得
      2100/01/01 12:15:05
        ちなみに,日付等の数字を文字変数に代入するには以下のようになります
        string dt,dy,dm,dd;
        dt=Secs2Date(DateTime,0);
        dy=dt[0,3]; dm=dt[5,6]; dd=dt[8,9];
        print dt,dy,dm,dd
            2100/01/01 2100 01 01

    print trunc(1), trunc(1.2), trunc(-1.5) // 絶対値が小さい方向の最も近い整数を返します
      1 1 -1

    print enoise(1) // -1〜1(可変)の範囲で一様な乱数を返します
      0.654505

    グラフ表示について
    マクロ中でグラフを表示させた時,規定の設定が反映されない事があります.
    それらの設定と,凡例の書式例です.
    Macro test3()
    Display $name2, $name0, $name1, $name3;
    ModifyGraph rgb($name1)=(0,0,65280),rgb($name2)=(0,39168,0),rgb($name3)=(44032,29440,58880);
    ModifyGraph tick=2,mirror=1,minor=1;
    Legend/C/N=text0/S=3/X=1.00/Y=1.00 "#"+num2str(n1)
    EndMacro




    3-6. Igorマクロの使用例
    igormacro1(Igor6.06Jで動作確認)

    内容の説明
    1. テキストファイルを連番でエクスペリメントに読み込む
    2. グラフのwindowを順にactivateする
    3. グラフのwindowを順に閉じる
    4. waveのn1〜n2の行に"nan"を書き込む
    5. 一定時間ごとにフォルダをチェックし,新しいデータがある時に処理
    6. 横河電機WE7000のバイナリデータを読み込み,ヘッダファイルの情報をデータに反映させる
    7. 短時間FFTにより,周波数スペクトルを生成
    8. データポイントを間引く

    // ##### 1. テキストファイルを連番でエクスペリメントに読み込む #####

    データが多数で,「データ」−「ウェーブをロード」を繰り返すのが面倒な時,データロードを自動化するマクロです.指定したn1〜n2の番号のファイルをロードします.後半で,平均データを別waveに記録します.

    Macro DataLoad_short2(n1,n2)
    variable n1,n2; string file1,fldname,fnn,name0,name1;
    silent 1; pauseupdate;

    // データフォルダの指定.
    fldname="L:\expdata\d200810kose";
    NewPath stuff, fldname

    do
    fnn=num2str(n1);

    // 以下はテクトロオシロ用にincrementされるファイル番号に対応.
    if (n1<=9)
    file1="TEK000"+fnn+".csv"; print file1; LoadWave/o/g/d/p=stuff/N=data file1;
    endif
    if ((n1>=10)%&(n1<=99))
    file1="TEK00"+fnn+".csv"; print file1; LoadWave/o/g/d/p=stuff/N=data file1;
    endif
    if ((n1>=100)%&(n1<=999))
    file1="TEK0"+fnn+".csv"; print file1; LoadWave/o/g/d/p=stuff/N=data file1;
    endif

    // name0,name1...という名前で読み込まれるので,別の名前で複製して読み込む.
    // このテクトロオシロは,データファイルの最初にヘッダ情報が書き込まれており,
    // Igorはヘッダ情報をdata0,data1として,その後のデータをdata2,data3として
    // 読みます.これらの状況は機種依存ですので,「データ」−「ウェーブをロード」
    // でデータを読み込んだ後,data*をテーブルで開いて中身を確認すると良いです.
    // (ポイント数が減ったりしていないか)
    // LoadWaveのオプションgをjに変更した方がうまくいく事もあります.

    name0="tek_"+fnn+"_t";
    name1="tek_"+fnn+"_v";
    duplicate/o data2 $name0;
    duplicate/o data3 $name1;

    // 読み込んだデータの1000-1020ポイントの平均値を,wavgという新しいwaveの
    // ファイル番号と同じポイントに書き込む.
    // // Make/N=200/D/O wavg; edit wavg;
    // WaveStats/Q/R=[1000,1020] $name1; print V_avg; wavg[n1]=V_avg;

    n1+=1;
    while(n1<=n2)

    Removepath stuff;
    EndMacro


    // ##### 2. グラフのwindowを順にactivateする #####

    多数のウィンドウに同じ処理(マーカを変更する,ラベルを付ける,legendを付ける,ShowInfoでカーソルを表示する,等)を施す時に使用出来ます.

    Macro window_activate_reverse(n1,n2)
    variable n1,n2; string index1,index2,name1,name2;
    silent 1; pauseupdate;

    do
    index1=num2str(n2);
    name1="Graph"+index1;
    DoWindow/F $name1
    // ### 各windowでの処理の追加は以下で
    // ModifyGraph mode=3,marker=19; // マーカの変更例
    // Label left "voltage (v)"; Label bottom "time (s)"; // ラベルの追加
    // Legend/C/N=text0/X=2.00/Y=2.00; // 「凡例」の追加
    // ShowInfo // カーソル表示;
    // ### ここまで
    n2-=1;
    while(n1<=n2)

    EndMacro


    // ##### 3. グラフのwindowを自動で閉じる #####

    手動でウィンドウを閉じる時,ダイアログが開き時間が掛かります.デフォルト名のグラフウィンドウを連続して閉じるマクロです.対応する番号が無い時は無視されるだけなので,例えばGraph11番以降を全て消したい時は,window_delete(11,1000) のようにコマンドに入力してもエラーは出ません.

    Macro window_delete(n1,n2)
    variable n1,n2; string index1,index2,name1,name2;
    silent 1; pauseupdate;
    do
    index1=num2str(n1);
    name1="Graph"+index1;
    DoWindow/F/K $name1
    n1+=1;
    while(n1<=n2)
    EndMacro


    // ##### 4. waveのn1〜n2の行に"nan"を書き込む #####

    Macro Del_number_add_nan(n1,n2)
    variable n1,n2; string index1,index2, name1; silent 1; pauseupdate;

    do index1=num2str(n1);

    | waveの名前をここで指定.
    name1="wave0";

    $name1[n1]=nan;
    n1+=1;
    while(n1<=n2)
    EndMacro


    // ##### 5. 一定時間ごとにフォルダをチェックし,新しいデータがある時に処理 #####

    次々とデータを取得する実験中に,自動でデータ処理を行うマクロです.
    StartAutoBackground()を走らせておくと,一定時間(間隔[s] のところ)おきにFolderCheck()が実行されます.FolderCheck()は,指定したフォルダに新しい保存データがあるか(前回処理した番号より大きい番号のファイルが存在するか否か,です.次に処理すべきデータ番号をShotNum[0]に記録しています.)をチェックします.新しいデータを見付けた時には指定した処理を行います.この例では,Combine_auto()という外部マクロを実行します.外部マクロに,データ読み込みやグラフ表示等の適当なマクロを割り当てておけば,忙しい実験中でもIgorがデータ点をプロットしてある程度の解析を進めてくれます.
    データファイルが大きく保存に時間が掛かる時,Igorがデータの存在を認識しても,まだ保存中で開けない事があります.この問題は,外部マクロの最初にwait_for_sec(2)などと書いておくと回避出来ます.
    一定時間おきの動作を停止するためには,StopAutoBackground()を使用します.
    フォルダ名,ファイル名や指定方法が環境に特化しています.詳細は,igormacro1をIgorで開いて,Jumbi()を実行した後でStartAutoBackground()を実行してみると分かり易いかもしれません.


    Proc FolderCheck() //新しいファイルの存在をチェック.
    variable n1,nf1,nf2; n1=ShotNum[0]; string fn1,fldname,fldname2;

    silent 1; pauseupdate;

    fn1=num2str(n1); fldname=FldN[0]; fldname2=FldN[1];
    GetFileFolderInfo/Z/Q fldname; //xfoldertime1=V_modificationDate; //更新時間をチェック7273.
    if (ShotNum[0]<=9) // 0番〜9番の処理
    GetFileFolderInfo/Z/Q fldname+"\\0000"+fn1+".wvf";
    endif
    if ((ShotNum[0]>=10)%&(ShotNum[0]<=99)) // 10番〜99番の処理
    GetFileFolderInfo/Z/Q fldname+"\\000"+fn1+".wvf";
    endif
    if ((ShotNum[0]>=100)%&(ShotNum[0]<=999)) // 100番〜999番の処理
    GetFileFolderInfo/Z/Q fldname+"\\00"+fn1+".wvf";
    endif
    nf1=V_flag;
    // print nf1

    GetFileFolderInfo/Z/Q fldname2; //xfoldertime1=V_modificationDate; //更新時間をチェック7275.
    if (ShotNum[0]<=9) // 0番〜9番の処理
    GetFileFolderInfo/Z/Q fldname2+"\\0000"+fn1+".wvf";
    endif
    if ((ShotNum[0]>=10)%&(ShotNum[0]<=99)) // 10番〜99番の処理
    GetFileFolderInfo/Z/Q fldname2+"\\000"+fn1+".wvf";
    endif
    if ((ShotNum[0]>=100)%&(ShotNum[0]<=999)) // 100番〜999番の処理
    GetFileFolderInfo/Z/Q fldname2+"\\00"+fn1+".wvf";
    endif
    nf2=V_flag;
    // print nf2

    if (nf1==0)
    xfoldertime=0; // WE7273のファイルが存在=0を返す.
    else
    xfoldertime=1; // ファイルが存在しない時は1を返す.
    endif

    EndMacro
    // 一定時間ごとにフォルダをチェックして,新しい番号のデータがある→処理,無い→何もしない.
    Macro StartAutoBackground() // バックグランド処理の実行マクロ.

    silent 1; pauseupdate;

    if( Exists("gHelloCnt") == 0 )
    Variable/G gHelloCnt=0;
    endif
    if( Exists(" xfoldertime") == 0 )
    Variable/G xfoldertime=0;
    endif
    if( Exists(" xfoldertime1") == 0 )
    Variable/G xfoldertime1=0;
    endif
    FolderCheck();
    print " ### RT1/WE7000 auto data processing program ### The next shot should be #", ShotNum[0]
    SetBackground myBackgroundFunc()
    gHelloCnt=0; CtrlBackground period=600, start // 600 period/510 = 間隔[s] 600:10s 1200:20s
    EndMacro

    Function myBackgroundFunc()
    NVAR xfoldertime=root:xfoldertime; NVAR xfoldertime1=root:xfoldertime1; NVAR gHelloCnt=root:gHelloCnt;
    xfoldertime1=xfoldertime
    Execute "FolderCheck()"
    // print/D xfoldertime,xfoldertime1
    if( gHelloCnt != -1) //強制的に終了するためのIF文.
    if( xfoldertime == 0 ) //データが存在すれば実行.
    print " ##### Data analysis sequence start", "at",Secs2Time(DateTime,1), "#####";
    Execute "Combine_auto()"
    endif
    // print "continue"
    return 0 //tell Igor to continue calling the background task
    endif
    print "good bye :-)"
    return 1 //tell Igor to stop background task
    End

    Macro StopAutoBackground() // 強制的にバックグラウンド処理を停めるマクロ.
    gHelloCnt=-1
    EndMacro

    // ****************************************
    // *** CONTROL BLOCK for 実験中の自動処理 *** ここまで
    // ****************************************

    Proc wait_for_sec(tw) // 動作待ちタイマー.
    variable t0,t1,t2,tw
    silent 1; pauseupdate;
    t0=ticks; t1=tw*60; t2=t0+t1;
    print "Timer macro is running. Waiting time is", tw, "s"
    do
    t0=ticks
    while(t0<=t2)
    EndMacro

    // ##### 6. 横河WE7000のバイナリデータ取り込み(WE7273 32chの場合) #####

    WE7000でデータ保存に「バイナリ」を選択すると,*****.hdrというテキスト形式のヘッダファイルと*****.wvfというバイナリファイルが作成されます.ファイルサイズは,テキスト保存と比較して1/10程度に小さくなります.ヘッダファイルに書かれた時間分解能や電圧スケール等の情報を利用して,物理量に直したデータwaveを作成します.この例ではWE7273というモジュールの32chデータを処理していますので,異なるチャンネル数や別モジュールを使用する際には変更が必要です.WE7116等の処理マクロがigormacro1にありますが,基本的には同じものです.


    Macro LoadWE7000_7273bnr_32ch(n1,n2)
    variable n1,n2,vf1,vf2
    variable nch1,nch2,nchs1,nchs2
    string index1, file1, file2, hdr1, wname1, fldname, fn1, fn2
    string bs,vr,vo,hr,ho,dt,tm,vmax,vmin
    string name0,name1,name2,name3,name4,name5,name6,name7,name8,fn,fnn;
    string name9,name10,name11,name12,name13,name14,name15,name16,name11_n,name12_n,name13_n,name16_n;
    string name17,name18,name19,name20,name21,name22,name23,name24,name25,name26;
    string name27,name28,name29,name30,name31,name32;
    variable bs1, bsv, hrv, vrv, vov, vmaxv, vminv

    silent 1; pauseupdate;

    newpath /o path1,FldN[0]; // 別ウェーブFldNでフォルダを指定している.
    newpath /o path2,FldN[10];

    do
    fnn=num2str(n1);

    name0="d"+fnn+"_0_"+sch1[0];
    name1="d"+fnn+"_1_"+sch1[1];
    name2="d"+fnn+"_2_"+sch1[2];
    name3="d"+fnn+"_3_"+sch1[3];
    name4="d"+fnn+"_4_"+sch1[4];
    name5="d"+fnn+"_5_"+sch1[5];
    name6="d"+fnn+"_6_"+sch1[6];
    name7="d"+fnn+"_7_"+sch1[7];
    name8="d"+fnn+"_8_"+sch1[8];
    name9="d"+fnn+"_9_"+sch1[9];
    name10="d"+fnn+"_10_"+sch1[10];
    name11="d"+fnn+"_11_"+sch1[11];
    name12="d"+fnn+"_12_"+sch1[12];
    name13="d"+fnn+"_13_"+sch1[13];
    name14="d"+fnn+"_14_"+sch1[14];
    name15="d"+fnn+"_15_"+sch1[15];
    name16="d"+fnn+"_16_"+sch1[16];
    name17="d"+fnn+"_17_"+sch1[17];
    name18="d"+fnn+"_18_"+sch1[18];
    name19="d"+fnn+"_19_"+sch1[19];
    name20="d"+fnn+"_20_"+sch1[20];
    name21="d"+fnn+"_21_"+sch1[21];
    name22="d"+fnn+"_22_"+sch1[22];
    name23="d"+fnn+"_23_"+sch1[23];
    name24="d"+fnn+"_24_"+sch1[24];
    name25="d"+fnn+"_25_"+sch1[25];
    name26="d"+fnn+"_26_"+sch1[26];
    name27="d"+fnn+"_27_"+sch1[27];
    name28="d"+fnn+"_28_"+sch1[28];
    name29="d"+fnn+"_29_"+sch1[29];
    name30="d"+fnn+"_30_"+sch1[30];
    name31="d"+fnn+"_31_"+sch1[31];
    name32="d"+fnn+"_32_"+sch1[32];

    // print name1,name10:

    if (n1<=9) // データファイル名のゼロの数を調整
    hdr1="0000"
    endif
    if ((n1>=10)%&(n1<=99)) // #10-99
    hdr1="000"
    endif
    if ((n1>=100)%&(n1<=999)) // ##100-999
    hdr1="00"
    endif
    if ((n1>=1000)%&(n1<=9999)) // #1000-9999
    hdr1=""
    endif

    index1=num2str(n1);
    file1=hdr1+index1+".wvf"; file2=hdr1+index1+".hdr"; // バイナリとヘッダファイル名

    GBLoadWave/T={16,4}/W=1/P=path1/N=data/B=1/O file1 // バイナリファイル
    // GBload: General Binary Loader
    // /T={fType, wType} 読み込む/作成ファイルのデータタイプ.
    // 32: 32bit符号付整数 16: 16bit符号付整数 2: 単精度浮動小数点 4: 倍精度
    // /W=w 一つのファイル内の配列の数 /B=1 リトルエンディアンを指定しないと誤動作

    Loadwave/j/k=2/P=path1/N=hd/Q file2 // ヘッダファイル

    // スペース区切りのヘッダファイルを分解して行列hd0に書き直す.
    hd0[0]="b0 b1 b2 b3 b4" // 5行ある事をを認識させるためにファイルを修正
    hd0[1]="No."+num2str(n1)+"__//YOKOGAWA_ASCII_FILE_FORMAT";
    Save/G/M="\r\n"/O/P=path2 hd0 as "hd"+num2str(n1)+".txt" // 後の処理で使うために新しく保存
    LoadWave/J/M/D/N=hd/P=path2/K=0/V={"\t, "," $",0,1}/Q "hd"+num2str(n1)+".txt" // 読み込み
    // これは文字列なので,str2numで変換が必要.
    print " ##### WE7000/7273 File number #",n1, "saved on", 'hd0'[28][1], 'hd0'[29][1],

    // バイナリデータから実験データ再構成に必要な情報を書き出す.WE7273 32chのヘッダファイルは,
    // VResolution 16, 35, 54, 73, 92, 111, 130, 149
    // VOffset 17, 36, 55, 74, 93, 112, 131, 150
    // HResolution 25, 44, 63, 82, 101, 120, 139, 158
    // HOffset 26, 45, 64, 83, 102, 121, 140, 159
    // Date 28, 47, 66, 85, 104, 123, 142, 161
    // Time 29, 48, 67, 86, 105, 124, 143, 162
    // vr=hd0[16]; vo=hd0[17]; hr=(hd0[25]); ho=hd0[26]; dt=hd0[28]; tm=hd0[29]
    // VResolution 縦軸の変換式 y=a*x+b のa VOffset y=a*x+b のb

    bsv=str2num('hd0'[15][1]); // BlockSize データのポイント数: 各ch共通で使う.
    hrv=str2num('hd0'[25][1]); // HResorution データのタイムステップ: 各ch共通で使う.

    // 一塊のwaveを各チャンネルごとのwaveにバラし,時間ステップを調整する.
    nch1=1; nch2=32;
    do
    nchs1=1
    do
    wname1=$("name"+num2str(nch1))
    duplicate/R=(bsv*(nch1-1),bsv*nch1-1)/O data0 $wname1 // 上で指定したname1-name32.
    SetScale/P x 0,hrv,"", $wname1
    // print nchs1, nch1 // hd0[][x]のx=1,2,3,4と,wave名に対応するch番号
    nchs1+=1; nch1+=1;
    while(nchs1<=4) // ヘッダファイルは4つづつ書かれている.
    while(nch1<=nch2)

    // 各waveの縦軸スケールを電圧に直す.
    nch1=1; nch2=32; nchs2=0;
    do
    nchs1=1
    do
    wname1=$("name"+num2str(nch1))
    vrv=str2num('hd0'[16+19*nchs2][nchs1]); // print "rvr", vrv, vrv*256.0, "hd0[",16+19*nchs2, "][",nchs1,"]", nch1
    vov=str2num('hd0'[17+19*nchs2][nchs1]); // print "vov", vov, "hd0[",17+19*nchs2, "][",nchs1,"]", nch1
    $wname1=(vrv*$wname1)+vov;
    // print nchs1, nch1 // hd0[][x]のx=1,2,3,4と,wave名に対応するch番号
    nchs1+=1; nch1+=1;
    while(nchs1<=4)
    nchs2+=1; // print nchs2;
    while(nch1<=nch2)

    n1+=1;
    while(n1<=n2)

    Removepath path1; Removepath path2;

    EndMacro


    // ##### 7. 短時間FFT #####


    図: 上記のマクロによる短時間FFTの解析例 (RT-1の純電子プラズマの周波数スペクトル).

    取り込んだデータに,Igorの組み込み関数を使用してSFFTを施し周波数スペクトルを作成します.


    Macro SFFTWE7000_7116bnr(n1,n2)
    variable n1,n2, nf1,nf2,nf;
    variable nch1,nch2,nchs1,nchs2
    string index1, file1, file2, hdr1, wname1, wname1f, fldname
    string bs,vr,vo,hr,ho,dt,tm,vmax,vmin
    string name0,name1,name2,name3,name4,name5,name6,name7,name8,fn,fnn;
    string name1f,name2f,name3f,name4f;
    variable bs1, bsv, hrv, vrv, vov, vmaxv, vminv
    variable fn0,fn1,fn2,n1o,fn1o,nn1,nn2,nm1,xsi,xsc,xtt,xscot,fullfreq,xts,xsam,nstart,nend;

    silent 1; pauseupdate;

    newpath /o path1,FldN[32];
    newpath /o path2,FldN[32];

    // nf=1; // Do FFT or not
    // if(nf==1)

    do
    fnn=num2str(n1);
    name0="d3_"+fnn+"_ch0";
    name1="d3_"+fnn+"_ch1";
    name2="d3_"+fnn+"_ch2";
    name3="d3_"+fnn+"_ch3";
    name4="d3_"+fnn+"_ch4";

    LoadWave/J/M/D/N=hd/P=path2/K=0/V={"\t, "," $",0,1}/Q "hd"+num2str(n1)+".txt" // 読み込み
    ExpMode[23]=str2num('hd0'[8][1]); // チャンネル数を読み込む

    nch1=ExpMode[24]; // FFTを掛けるチャンネル(WE7000での)指定

    do

    wname1=$("name"+num2str(nch1))
    xsi=str2num('hd0'[25][1]); // サンプル数
    xsc=str2num('hd0'[15][1]); // サンプル間隔
    xtt=xsi*xsc; // total time
    xsam=500; // SFFTのサンプル数.偶数.1000とか.
    print "sampling interval", xsi,"[s]; total sampling numbers", xsc,"; SFFT sample", xsam,;
    xscot=xsc/xsam; // totalsample/sample 小ブロック数
    fullfreq=1/xsi*0.5/1000; // full frequency scale [kHz]
    xts=xsi*xsam; // time step
    print "full frequency scale", fullfreq,"[kHz]; time step",xts/2, "[s]; total time", xtt,"[s]";

    nf1=0; nf2=2*xscot-2; n1o=nf1;

    wname1f=wname1+"_FFT"; // 新たに作るFFT結果wave
    print wname1f

    // FFT対象のwaveを表示する.
    // Display $wname1; ModifyGraph tick=2,mirror=1,minor=1; Legend/C/N=text0/S=3/X=2.00/Y=2.00;

    Make/N=(2*xscot-1,xsam/2+1)/D/O FFT_m; // Edit FFT_m.id;

    SetScale/I y 0,fullfreq,"kHz", FFT_m;
    SetScale/P x xsi*xsam/2,xsi*xsam/2,"s", FFT_m
    // この行列は,横が周波数,縦が時間変化です.縦のマス数はxscot.

    do // 行列を作る.
    nstart=nf1*(xsam/2); nend=nf1*(xsam/2)+xsam-1;
    FFT/OUT=3/WINF=Hanning/RP=[nstart,nend]/DEST=W_FFT $wname1
    FFT_m[nf1][]=W_FFT[q]
    nf1+=1;
    while(nf1<=nf2)

    duplicate/O FFT_m $wname1f
    Display;AppendMatrixContour $wname1f
    TextBox/C/N=text0/X=1.00/Y=1.00 "#"+fnn+"_3_"+num2str(nch1)
    SetAxis left 0,fullfreq ;DelayUpdate
    SetAxis bottom 0,xtt; // print xtt;
    ModifyContour $wname1f labels=0,autoLevels={*,*,30}
    ModifyGraph tick=2,mirror=1,minor=1
    AppendImageToContour(wname1f,200)
    // ModifyImage $wname1f ctab= {*,0.1,Rainbow,1}
    ModifyImage $wname1f ctab= {*,0.1,Rainbow,1} //{*,***,Rainbow,1} この***を変えるとカラースケールの最大値を可変にできる.
    RemoveContour $wname1f

    // name12="d"+num2str(nn1)+"_ch2"; Display $name12; ModifyGraph tick=2,mirror=1,minor=1; Legend/C/N=text0/S=3/X=2.00/Y=2.00;

    nch1+=1;
    while(nch1<=ExpMode[25])

    n1+=1;
    while(n1<=n2)
    Removepath path1; Removepath path2

    // endif
    EndMacro

    // ##### 8. データポイントを間引く #####

    例えば,測定対象の現象の速さよりオシロのサンプリングが高速過ぎてデータが冗長な時,ファイルサイズを小さくする際に使用します.

    Macro Mabiki()
    variable n1,n2,n11; string name1,name2;
    silent 1; pauseupdate;

    // Make/N=201/D/O wtest; wtest=x; // 元のwave作成(マクロ実行前にコマンドで実行)
    // Make/N=21/D/O wtest2; wtest2=nan; // 間引き後のwave作成(同上)
    // Edit wtest, wtest2;

    n1=0; n2=200;

    name1="wtest"; name2="wtest2" // waveの名前指定
    n1=0; n11=0;

    do
    if( mod(n1,10) == 0 ) // 10おきに新しいwaveに書き込む
    print n1,n11
    $name2[n11]=$name1[n1]
    n11+=1;
    endif
    n1+=1;
    while(n1<=n2)

    SetScale/P x 0,10,"", wtest2;
    Display wtest,wtest2; ModifyGraph mode(wtest2)=3,marker(wtest2)=19

    EndMacro



    東大新領域吉田研 齋藤晴彦
    ホーム 研究発表 履歴 その他