2 次元データの補間2010年1月13日 | |
はじめにParaView を使って、VTK の 2 次元点データ列から、CSV 形式の任意の 2 次元点列に値を補間する。 バージョンParaView 3.6.2 ファイルサンプルとしてお使いください。VTK ファイルのほうは ZIP 圧縮しているので、展開してください。 任意の点におけるデータの取得ParaView でデータを表示させたとき、そこから任意の点でのデータを得るには、フィルタの Probe Location を使う。 メニューの Filters から Probe Location を選ぶと、点の座標を入れるところがあるので、そこに座標値を入れて Apply ボタンを押すと、その座標値におけるデータが得られる。マウスポインタを画面上に置いてキーボードの 'p' を押すことで、ポインタが指している座標値を設定することもできる。 具体的な値を知るには、Information タブの Data Arrays を見る。レンジで表示されてあるが、1 点分のデータしかないので、最小値も最大値も同じである。あるいは、画面右上の小さいボタンで画面を分割して、Spreadsheet View で見るという手もある。 ちなみに、Number of Points と Radius を設定すると、指定した座標周りに設定した半径で点を適当に配置してくれる。 この機能を使えば、2 次元点データをデローニー分割した後、任意の点での値を取得することができる。とはいえ、値を取りたい位置がたくさんあると、いちいち手でやってはいられない。Python での自動化を試みよう。 Python による自動化Python スクリプトを示す。 vtkToPoint.py # vtkToPoint import os def vtkToPoint(vtkFilename, csvFilename): reader = LegacyVTKReader(FileNames=vtkFilename) view = GetActiveView() view.StillRender() d = Delaunay2D(reader) view.StillRender() p = ProbeLocation() Show(p) pt = p.ProbeType data = p.PointData['point_scalars'] inFile = open(csvFilename, "r") inFile.readline() vtkBasename = os.path.splitext(vtkFilename)[0] csvBasename = os.path.splitext(csvFilename)[0] outFile = open(vtkBasename + '-' + csvBasename + '.csv', 'w') outFile.write('x,y,value¥n') for line0 in inFile: line = line0[0:len(line0)-1] item = line.split(",") x = float(item[0]) y = float(item[1]) pt.Center = (x, y, 0.) view.StillRender() v = data.GetRange()[0] outFile.write('%f,%f,%f¥n' % (x, y, v)) inFile.close() outFile.close() 使い方は、まずメニュー Tools から Python Shell を開き、Run Script ボタンで上のスクリプトを読み込む (2020.10.24 追記: ParaView 5.8.1 だと Python Shell は View メニューにある)。そして、以下のように関数を呼び出す。 >>> vtkToPoint('contour.vtk', 'point.csv') 第 1 引数がデータの VTK ファイル、第 2 引数が値を取りたい点列が書かれた CSV ファイルである。上の場合、'contour-point.csv' という点データ列の CSV ファイルが書き出される。入力する点列の CSV ファイルの書式は、以下のように 1 行目が項目のタイトル、それに続いて 2 次元座標値が並んでいる。 x,y 1.374302387,3.228690147 -4.621094227,-11.71187782 -2.019116879,2.14136982 ... 作業をするにあたって、作業フォルダをカレントのフォルダにするために、Windows 版であれば、ParaView のアイコンを作業フォルダにコピーし、アイコンを右クリック、プロパティでショートカットタブの作業フォルダを空欄にし、そのアイコンで ParaView を起動するとよい。ただし、ヘルプを開けなくなるが。 スクリプトの内容を説明する。 reader = LegacyVTKReader(FileNames=vtkFilename) view = GetActiveView() view.StillRender() LegacyVTKReader() で VTK ファイルを読み込む。現在のビューを取得して、StillRender() を呼び出す。これが何なのか知らないが、これがないとデータが正しく取れない。以下、ことあるごとに呼び出す。 d = Delaunay2D(reader) view.StillRender() フィルタの Delaunay2D の適用。 p = ProbeLocation() Show(p) フィルタの Probe Location を適用する。ここで表示する。データを取るだけなので、わざわざ表示しなくてもよさそうなものだが、こうしないとちゃんとデータが取れない。 pt = p.ProbeType data = p.PointData['point_scalars'] 後で使うために ProbeLocation の ProbeType の参照を得る。また、取り出すデータとして、'point_scalars' を指定している。もし別のデータを取得したければ、このあたりを書き換えること。 その後、入力用と出力用のファイルを開いて、座標値を読み込んで、以下でデータを取る座標を指定している。 pt.Center = (x, y, 0.) view.StillRender() そして、値の取得。 v = data.GetRange()[0] レンジから値を得ている。最小値と最大値は同じ値なので、最小値を取ってその点の値としている。 入力データと出力データを比べたのが以下の絵である。左が元のデータ、右が補間されたデータ。 ![]() 点の数が少ないのでちょっとぼんやりして見えるが、まあよさそうである。 | |
PENGUINITIS |