ソフトウェア/Igor のバックアップ差分(No.4)
更新- 追加された行はこの色です。
- 削除された行はこの色です。
[[公開メモ]] #contents * Igor とは [#k3f1dcd4] データ解析に Wave Metrics 社の Igor Pro を使っています。 なかなか癖のあるソフトですが、 Igor 上でプログラムを組むことでかなり複雑なデータ解析も自動化できていろいろ捗ります。 ここには使い回しの効きそうなコード例を上げていこうと思います。 公式のオンラインヘルプはこちら: http://www.hulinks.co.jp/support/igor/programming/index.html * 分野別記事へのリンク [#cb75dc8d] #ls2("ソフトウェア/Igor") * あるグラフ上に表示されたウェーブの一覧を表示する [#n02b667a] * Igor のマルチスレッド対応 [#w13d601c] Igor Pro 6.1 から、マルチスレッド対応が強化されたそうです。 LANG:Igor string graph_name = "Graph1" string traces = TraceNameList(graph_name, ";", 1) variable i for(i = ItemsInList(traces) - 2; i>=0; i-=1) print StringFromList(i, traces) endfor wave0 = any_expression(x) 画像の一覧なら、TraceNameList ではなく ImageNameList を呼べばいい。 のような代入文で時間がかかっている場合、 LANG:Igor string graph_name = "Graph1" string images = ImageNameList(graph_name, ";", 1) variable i for(i = ItemsInList(images) - 2; i>=0; i-=1) print StringFromList(i, images) endfor MultiThread wave0 = any_expression(x) * グラフウィンドウ上の選択領域を得る [#d6fd38cf] とするだけで、個々の座標値に対する計算を異なるスレッドで行ってくれます。 グラフ上をマウスで斜めにドラッグすると矩形領域を選べますが、 この範囲を Igor では Marquee と呼んでいます。 当然、wave の個々の座標の値の間に依存関係がある場合にはうまくいきませんが、 独立に計算できる場合にはこれだけでかなり速度が上がります。 使用例 ** より高度なマルチスレッド [#fe54477c] LANG:Igor // 与えられた座標がグラフの選択領域に含まれているかどうか返す function IsPointInSelectedRegion(x, y) variable x, y string graph_name = "Graph1" struct Rectangle selected_region GetMarqueeRegion(graph_name, selected_region) return IsPointInRect(x, y, selected_region) end もっと複雑なことをしたい場合には、 ThreadGroupCreate / ThreadStart / ThreadGroupPutDF / ThreadGroupGetDF / ThreadGroupWait / ThreadGroupRelease といった関数を使うことで、きめ細やかなマルチスレッド制御を行えます。 コード 実際やってみると、メモリ確保などに時間がかかっていることも多いようで、 単純にスレッド数倍もの速度向上は望めませんが、シングルスレッド比で 2倍くらいの速度は簡単に出せるようでした。 LANG:Igor // 矩形領域を格納するための構造体 Structure Rectangle double left double right double top double bottom EndStructure // 指定された名前のグラフから選択範囲を得る // 選択されていなければ全範囲 (left, bottom 軸で) を返す function GetMarqueeRegion(graph_name, region) string graph_name Struct Rectangle ®ion GetMarquee/W=$graph_name left, bottom if(!V_Flag) GetAxis/q/W=$graph_name bottom V_Left = V_min V_Right = V_max GetAxis/q/W=$graph_name left V_Top = V_min V_Bottom = V_max endif region.left = V_Left region.right = V_Right region.top = V_Top region.bottom = V_Bottom end // x, y で指定された点が rect 領域に入っているかどうかを返す function IsPointInRect(x, y, rect) variable x, y Struct Rectangle &rect variable result result = rect.left <= x result = x <= rect.right && result result = rect.top <= y && result result = y <= rect.bottom && result return result end 例えば、Intel Core i7-3520M @ 2.9GHz + Windows 7 (64bit) で 1024 本のスペクトルに対して解析を行った結果、 * グラフ上の選択範囲を設定する [#dcd89a94] - シングルスレッド = 11.0 秒 - マルチスレッド = 4.3秒 SetMarquee を使えばいいのですが、単位をポイントに直さなければならないので、 PixelFromAxisVal と ScreenResolution を呼んで変換します。 という結果が得られました。 コード LANG:Igor // 下軸、左軸の値を指定してグラフの選択範囲を設定する function image_mouseup(x1, y1, x2, y2) variable x1, y1, x2, y2 x1 = PixelFromAxisVal("image", "bottom", x1) / ScreenResolution * 72 x2 = PixelFromAxisVal("image", "bottom", x2) / ScreenResolution * 72 y1 = PixelFromAxisVal("image", "left", y1) / ScreenResolution * 72 y2 = PixelFromAxisVal("image", "left", y2) / ScreenResolution * 72 SetMarquee/w=image, x1, y1, x2, y2 end
Counter: 14299 (from 2010/06/03),
today: 3,
yesterday: 0