Agenda
本講習の目的ParaViewによる可視化中級編：! ParaViewにおけるPythonスクリプティングの概要を学ぶ

スクリプティングを中心にTopics
担当: 大嶋拓也 (新潟大学)

! 序: ParaViewのクライアント・サーバモデル- 当該モデルにおけるPython適用の整理

オープンCAEシンポジウム2011
2011年12月1日(木)!

プログラミング・インターフェイス: 3種類!

クライアント・サーバ形態: 4形態!

Pythonの適用可能箇所: 9箇所! 本編: 9箇所それぞれのPythonスクリプティングを概説
1

2

ParaViewのクライアント・サーバ・モデル

序: ParaViewのクライアント・サーバモデル

Partitioned
data

Partitioned
data

Partitioneddata

Data source*Data source*Data source*

VTK pipeline(Filters)
VTK pipeline(Filters)
VTK pipeline(Filters)
Parallel renderer
Server process 0

Parallel renderer
Server process 1
Parallel renderer
Server process N

- 当該モデルにおけるPython適用の整理

Client*Data Source: データファイルリーダ、またはFilters!Sourcesの各項目
34

ParaViewにおけるPythonの適用(1): 概要

ParaViewにおけるPythonの適用(2): インターフェイス! クライアント・サーバ・モデルにおけるPythonの適用形態は多様! Python Calculator

VTK Pythonの簡略化記法。サーバ側で実行される- 典型的には4ケース(次々スライド以降)

Data source! それぞれにおいてPythonの適用が可能!

! 3種のプログラミング・インターフェイスFilters

Python Calculator: パイプライン内でのデータ演算に使用、下記: VTKの数百のクラスをPythonでラッピングしVTK Pythonたもの。パイプライン内でのデータ演算、生成に使用。主にサーVTK Python

バ側で実行される(例外: servermanager.Fetch())
import vtkParaView PythonServer! ParaView Python! 目的に応じて、どの部分でPythonスクClient: ParaView全体の実行制御に使用。主にクライアント側で実行される(例外: pvbatch, CoProcessing)

リプティングを使用すべきか見極める

import paraview
5

6

ParaViewにおけるPythonの適用(3): paraview

ParaViewにおけるPythonの適用(4): pvpython! GUIクライアントとParaViewサーバによる、通常の利用形態

! pvpython: ParaView Python readyなPythonインタプリタ! pvpythonはクライアントとして動作

Data sourceData sourceProgrammable Source

FiltersProgrammable Source

Filters

Python CalculatorProgrammable Filter

Python CalculatorProgrammable Filter

Python Tracepvserver

paraview

pvserver

Python Macro
Python Shellpvpython
7

ParaView Python
8

ParaViewにおけるPythonの適用(5): pvbatch

ParaViewにおけるPythonの適用(6): CoProcessing! pvbatch: ParaView Python readyなPythonインタプリタ! シミュレーション・コードに、ParaViewをライブラリとして組み込む! pvbatchはサーバとして動作、クライアント無し

Simulation data! シミュレーション・コード! 並列実行の場合は、pvbatchをmpirunで並列実行させるの対応作業が必要

Data source

! プロセス0がPythonスクリプトを解釈、1以降は0の指示により動作

Programmable Source

Data sourceてのデータをオン・メモリ

Programmable Source
Filters
Filters

! ディスクI/Oを介さず、全Python Calculator

Python CalculatorProgrammable Filter

Programmable Filter

ParaView Python
CoProcessinglibrary
Simulation codeParaView Python
pvbatch
9で処理! 大規模計算に最適! 全プロセスがPythonスク
リプトを解釈 (SymmetricMPI mode)
10

ParaViewにおけるPythonの適用(7): 一覧
! 以上まとめると
1. Python Calculator
2. Programmable Filter
3. Programmable Source

Python Calculator
VTK Python

1. Python Calculator

4. Python Trace
5. Python Macro
6. Python Shell
7. pvpython

ParaView Python

8. pvbatch
9. CoProcessing! 以下、順に説明
1112

Python Calculator (1): 概要

Python Calculator (2): 使用例1 フィールドに関数を適用

! フィルタの一種、Programmable Filterの簡易版! 最も簡単なPythonスクリプティング (VTK Pythonの簡略化記法)

1. Waveletソースを作成。
Waveletソースは、RTDataという節点フィールドを持つ! フィールド・データの一様な演算に便利! abs, cross, curl, ...など関数一覧、詳細な使い方:- http://paraview.org/Wiki/ParaView/Users_Guide/

6. inputs[0]のフィールド・データを、出力に含めるかPython_Calculator! 複数の入力間の演算も可能

7. クリック

2. 選択

- inputs[番号]: 入力データセットの選択!

.PointData['フィールド名']: 節点フィールドの選択!

.CellData['フィールド名']: セルフィールドの選択!

.Points: 節点座標

3. 計算式

4. Cell/Point Dataの別
5. 計算結果のフィールド名

13

Python Calculator (3): 使用例2 データセット間の差分

Python Calculator (4): 注意点! 2つのデータセットの差を取る例

! 出力メッシュは、inputs[0]のものとなる! フィールド・データのサイズは、全ての入力データセットで等しい必

4. Control (MacはCommand)キーを使いWavelet1、2の順に選択、その後PythonCalculatorを選択

3. クリック

1. 前スライドで作成した
PythonCalculator1を消去。かわりにWaveletソースWavelet2を追加し、2.の変更を行う

2. Wavelet2のみ、1に変更

14

要がある
- 通常は、同一のメッシュ(形状・節点数・セル数・トポロジ)に対して使用する- 並列実行時には、全てのデータセットがプロセス間で同じように配分されている必要がある! フィールド・データはNumPy配列として扱われる

6. クリック
5. 以下を入力
inputs[1].PointData['RTData']- inputs[0].PointData['RTData']- NumPyと同様な演算が可能

15

16

Programmable Filter (1): 概要
! ParaViewフィルタに用意されていない機能を、Pythonによって自分で作成できる! サーバ側で実行される- サーバの並列実行時は並列実行される

2. Programmable Filter! プログラミング・インターフェイス: 以下の混在が可能- Python Calculator- VTK Python: VTKの知識が必要! VTKデータ表現とNumPyデータ表現の相互変換が可能- NumPyによる演算が可能

17

18Programmable Filter (2): 例1 Python Calculator記法

Programmable Filter (3): 例2 VTK Python! Python Calculatorの例2(データセット間の差分)と同じ処理を、! 同じ処理を、VTK Pythonによって記述

Python Calculator記法によって記述

input0 = self.GetInputDataObject(0, 0)
input1 = self.GetInputDataObject(0, 1)! Wavelet1、2ともに選択後、Programmable Filterを選択

data0 = input0.GetPointData().GetArray('RTData')
data1 = input1.GetPointData().GetArray('RTData')! Script: 欄に以下を入力、Apply
idi0 = inputs[0]idi1 = inputs[1]diff = idi1.PointData['RTData'] - idi0.PointData['RTData']
output.PointData.append(diff, "result")

diff = vtk.vtkFloatArray()diff.SetNumberOfTuples(data0.GetNumberOfTuples())
diff.SetName('result')
for i in range(data0.GetNumberOfTuples()):
diff.SetValue(i, data1.GetValue(i) - data0.GetValue(i))! フィールド・データはNumPy配列として扱われる

output = self.GetOutputDataObject(0)output.GetPointData().AddArray(diff)! Pythonのforループは効率が悪い、処理内容がわかりにくい! より高度な処理を行いたい(メッシュも操作したいetc)- VTK Python: 次スライド- VTKデータ・NumPy配列相互変換: 次スライド
1920

Programmable Filter (4): 例3 NumPyとの相互変換
! 同じ処理を、VTKデータ・NumPy相互変換を用いて記述
from paraview.vtk import dataset_adapter as DA
input0 = self.GetInputDataObject(0, 0)
input1 = self.GetInputDataObject(0, 1)

3. Programmable Source

data0 = input0.GetPointData().GetArray('RTData')
data1 = input1.GetPointData().GetArray('RTData')
data0np = DA.vtkDataArrayToVTKArray(data0) # VTK to NumPy
data1np = DA.vtkDataArrayToVTKArray(data1) # VTK to NumPy
diffnp = data1np - data0np # NumPy operation!
diff = DA.numpyTovtkDataArray(diffnp) # NumPy to VTK
diff.SetName('result')
output = self.GetOutputDataObject(0)output.GetPointData().AddArray(diff)
2122

Programmable Source (1): 概要・例 ポリゴンメッシュ生成

Programmable Source (2): パイプラインのクリア

! Sources!Programmable Source! ここで、ツールバー上のDisconnectボタンをクリックして、パイプラ- Programmable FilterのSource版

インをクリアして下さい! 四角形1つのポリゴンメッシュ生成例

クリック

pdo = self.GetPolyDataOutput()
pdo.Allocate()
pts = vtk.vtkPoints()
pts.InsertNextPoint(-1, -1, 0)
pts.InsertNextPoint(1, -1, 0)
pts.InsertNextPoint(1, 1, 0)
pts.InsertNextPoint(-1, 1, 0)
pdo.SetPoints(pts)ptIds = vtk.vtkIdList()
ptIds.InsertNextId(0)ptIds.InsertNextId(1)ptIds.InsertNextId(2)ptIds.InsertNextId(3)pdo.InsertNextCell(vtk.VTK_QUAD, ptIds)

23

24

Python Trace / Python Macro (1): 概要
! ParaView GUI上で行った操作を、ParaView Pythonスクリプトとして書き出す! 書き出されたスクリプトは、Macros...

4. Python Trace

メニューに登録して実行できる

5. Python Macro- 操作の自動化: ParaView Python

を知らなくても、バッチ処理スクリプ
トを作れる- 書き出されたコードを読んで、ParaView Pythonを学習
25

26

Python Trace / Python Macro (2): 例 ソースの作成

Python Trace / Python Macro (3): 例 ソースの作成

! ソースを1つ生成する例! File!Saveを選択、適当なフォルダに保存

1. Tools!Start Traceを選択- ParaView Pythonスクリプトとして保存される

2. Sources!Waveletを選択、Standard Deviationを1とし、Apply
3. Tools!Stop Traceを選択! File!Save As Macro...を選択、ダイアログのデフォルトフォルダ! スクリプトが生成され、スクリプト・エディタに表示されるに保存- ファイルの内容はFile!Saveによる保存ファイルと同一- Macrosメニューに登録される- ツールバーにも登録される

27

28

Python Trace / Python Macro (4): 例 ソースの作成
! 登録されたマクロの削除: Macros!Delete...!削除したいマクロを選択

6. Python Shell! ここで、ツールバー上のDisconnectボタンをクリックして、パイプラインをクリアして下さい
クリック

29

30

Python Shell (1): 概要

Python Shell (2): モジュールのインポート

! Tools!Python Shellを選択: paraview上のPythonコンソール! ParaView Python! ParaView Pythonを実行可能- paraview.simple: ひととおりの制御を行う! スクリプトを手で入力しながら実行 ("#キーで入力履歴を辿れる)- paraview.servermanager: 高度な制御を行う- paraview.vtk: ParaView Python/VTK Pythonの混在

ParaViewモジュールは、既にインポートされた状態になっている
スクリプトの読込み: 保存したPython Traceスクリプトを読込んでみて下さい。読込みを確認したらDeleteをクリッックし削除! paraview.simpleモジュールのインポート
from paraview.simple import *- Python Console上では不要

コンソール画面のクリア
Pythonインタプリタのリセット! ここでは主にparaview.simpleモジュールを扱う

コンソールを閉じる

- それ以外では必要! 以下のようにすると、どちらの場合も対応できる
31

try: paraview.simple
except: from paraview.simple import *32

Python Shell (3): ソースの作成

Python Shell (4): ソースのプロパティ

! ソースの作成! プロパティ名も、基本的にGUIのプロパティ・パネルに表示される

wavelet1 = Wavelet()名前からホワイトスペースや特殊文字を除いたもの- 全ソースとフィルタについて、生成のための関数がある- 例外多数! プロパティ一覧- 関数名は、GUI上に表示される名前からホワイトスペースや特dir(wavelet2)
help(wavelet2)

殊文字を除いたもの! ソースの作成と同時に、プロパティを設定できる- ただし、ParaViewが内部的に使用するプロパティも多い

wavelet2 = Wavelet(StandardDeviation=1)! ユーザレベルで設定するプロパティの一覧
wavelet2.ListProperties()- GUI上のプロパティパネルに、設定値が反映される! 具体的な設定方法は、Python Traceでの確認がおすすめ! 作成されたWaveletオブジェクトの実体はサーバ上に存在- ParaView Pythonは代理オブジェクト(プロキシ)を操作
33

34

Python Shell (5): オブジェクトの削除Python Shell (6): レプレゼンテーションの作成

! オブジェクトのパイプラインからの削除! アクティブなソース(直前に作成したソース)のレプレゼンテーション

Delete(wavelet2)を作成し、可視状態にする- ソース、フィルタ、レプレゼンテーション、レンダー・ビュー等、全

drw2 = Show()! レプレゼンテーションをSurface With Edgesにするてこれで削除できる

drw2.Representation='Surface With Edges'! さらに、メモリ上から完全に削除するには
del wavelet2! RTDataの最小値$最大値範囲で色付けする
drw2.ColorArrayName='RTData'r = drw2.Input.PointData[drw2.ColorArrayName].GetRange()
drw2.LookupTable = MakeBlueToRedLT(r[0], r[1])! 以下がエラーになることで、オブジェクトの削除を確認
wavelet2! 後の演習を続けるため、再度wavelet2を作成("キーを使用)! レプレゼンテーションには、多くのプロパティがある。詳細はdir(drw2)
help(drw2)

wavelet2 = Wavelet(StandardDeviation=1)- または、Python Trace- パイプライン・ブラウザ上では、Wavelet3
3536

Python Shell (7): レンダー・ビューの作成

Python Shell (8): 可視・不可視状態の制御

! ビューをレンダリングし、レンダー・ビューを取得する! 指定したソースを可視状態にする

rv = Render()Show(wavelet1)
Render()! ビューのサイズを変更する (Python Consoleでは効かない)! アクティブなソース(直前に作成したソース)を不可視状態にする
Hide()

rv.ViewSize = [1024, 768]

! 時系列データに対して、現在の時刻を指定する(後で使用)! 指定したソースを不可視状態にする

rv.ViewTime = 0.0

Hide(wavelet1)
Render()! レンダー・ビューには、多くのプロパティがある(特にカメラ関係)。
! アクティブでないソースには、Show()/Hide()の後にRender()

詳細はdir(rv)help(rv)

が必要- または、Python Trace
3738

Python Shell (9): アクティブなソース、ソース一覧

Python Shell (10): 1入力フィルタの作成・設定

! アクティブなソースを取得する! アクティブなソースに対して、フィルタを作成
threshold = Threshold(ThresholdRange=[0, 150])
Show()
Render()GetActiveSource()! アクティブなソースを変更する! しきい値を変更して、フィルタを再度実行

SetActiveSource(wavelet1)- パイプライン・ブラウザ上のハイライトも変更される

threshold.ThresholdRange = [200, 250]
Render()! ソースの一覧を取得する! フィルタの入力を変更

GetSources()- 一覧は('ソース名',threshold.Input = wavelet2
Render()'ID')のタプルをキーとするPythonの辞書形式リストになっている。リストからいずれかの要素を抽出- フィルタの作成時にも、Inputキーワード引数によってアクティするには、例えば以下のようにする(IDは状況により異なる)

ブなソース以外を指定可能

GetSources()[('Wavelet1', '291')]
3940

Python Shell (11): 複数入力フィルタの作成・設定

Python Shell (12): 画像の保存

! Python Calculatorの例2(データセット間の差分)を、ParaView! 現在のビューの画像を、適当なフォルダにview.pngのファイルPythonによって記述名で保存(パスは適宜読み替えて下さい)! wavelet1、wavelet2を入力としてPython Calculatorを作成

WriteImage('/Users/ohshima/Desktop/view.png')

pycalc = PythonCalculator(Input=[wavelet1, wavelet2])! 計算式スクリプトをExpressionプロパティに設定! view.pngが作成されているのを確認したら、Disconnectをクリッ

pycalc.Expression="inputs[1].PointData['RTData'] - inputs[0].PointData['RTData']"

クしてパイプラインをクリアして下さい- Programmable Source/Filterでも、同様にScriptプロパティにクリック

Pythonスクリプトを設定可能 (Python Trace参照)! レプレゼンテーションを設定
drpc = Show()
drpc.ColorArrayName = 'result'r = drpc.Input.PointData[drpc.ColorArrayName].GetRange()
drpc.LookupTable = MakeBlueToRedLT(r[0], r[1])Render()41

42

Python Shell (13): データファイルの読込み1Python Shell (13): データファイルの読込み2

! ParaViewData内のフォルダに移動して、以降のフォルダ・パス入! データ・リーダを明示的に指定する場合力を削減(パスは適宜読み替えて下さい)- ファイル名を1つだけ指定するリーダ

import os
os.chdir('/Users/ohshima/Desktop/ParaViewData-3.12.0/Data')

box = ExodusIIReader(FileName='box.ex2')- 複数のファイルを時系列として認識するリーダ
mc = XMLStructuredGridReader(FileName=['multicomb_0.vts','multicomb_1.vts'])! データフォーマットをParaViewに認識させる場合- 主に拡張子で判断される!

can = OpenDataFile('can.ex2')
Show()
rv = Render()LegacyVTKReaderでは、FileNameでなくFileNames! 今回はこれらのデータを使わないので、確認したら消去
Delete(box)del boxDelete(mc)del mc4344

Python Shell (14): 時系列データのアニメーション

Python Shell (15): VTK Pythonの使用

! アニメーション作成は、AnimateReader()を使うのが簡単! ビルトイン・サーバ・モードの場合に限り、ParaView PythonでサAnimateReader(can, filename='../can.avi')

ーバ上のVTKオブジェクトの取得が可能- 連番PNGファイルにするなら

canvtk = servermanager.Fetch(can)!

40以上のファイルが生成されるので注意- canvtkは、VTKの実体オブジェクト(プロクシではない)

AnimateReader(can, filename='../can.png')- VTK Pythonによる操作が可能! または、時刻ステップのリストが、リーダのTimestepValuesプ

can.GetClassName()
canvtk.GetClassName()
canvtk.GetNumberOfBlocks()

ロパティに格納されているのを利用
can.TimestepValues! Python ShellのCloseをクリックして、Python Shellを閉じて下さい- レンダー・ビューのViewTimeを操作すれば良い
for i in range(len(can.TimestepValues)):rv.ViewTime = can.TimestepValues[i]Render()WriteImage('../can_' + str(i) + '.png')

45

46

pvpython / pvbatch
! pvpython / pvbatch: ParaViewモジュールをimportできるよう、モジュール検索パス(sys.path)を設定済みのPythonインタプリタ! pvpython: クライアントとして動作

7. pvpython- pvserverへ接続

8. pvbatch

c = Connect('serverhost', 11111)! pvbatch: サーバとして動作するので、サーバへの接続は不要。
pvbatch自体をmpirunで並列実行させる
mpirun -n 2 pvbatch batchScript.py- Pythonスクリプトを解釈・実行するのはプロセス0のみ、プロセス1以降はプロセス0の指示により動作
47

48

CoProcessing (1): 概要
! シミュレーション・コードにParaViewをライブラリとしてリンク! シミュレーション・コードのメモリ上のデータをCoProcessing APIを通じて受取り、ディスクI/Oを介さず処理を行う! 処理結果として、以下を出力

9. CoProcessing- パイプライン処理後のデータセット(VTK XML形式)- 可視化画像! 可視化パイプラインは、Pythonスクリプトで表現する- CoProcessing特有のコードが追加されたParaView Python!

付属プラグイン(CoProcessingPlugin)により、GUI上のパイプラインをスクリプトとして書出し可能

49

50

CoProcessing (2): シミュレーション・コード側の対応1

CoProcessing (3): シミュレーション・コード側の対応2! シミュレーション・コード側では以下を追加! 時刻ステップごとのループ内- C++の場合。ヘッダ・ファイルのインクルードは省略

dataDesc->SetTimeData(timeValue, timeStep);!
if(processor->RequestDataDescription(dataDesc) != 0)!
{!
vtkCPInputDataDescription *inputDesc!
= dataDesc->GetInputDescriptionByName("input");!
inputDesc->SetGrid(dataObject);!
inputDesc->SetWholeExtent(wholeExtent);!
processor->CoProcess(dataDesc);!
}!

! セットアップ部分- MPI、コプロセッサ初期化、Pythonスクリプトの読込み
MPI_Init(&argc, &argv);!
vtkCPProcessor *processor = vtkCPProcessor::New();!
processor->Initialize();!
vtkCPPythonScriptPipeline *pipeline =!
vtkCPPythonScriptPipeline::New();!
// Load Python script!
if(pipeline->Initialize(pythonScriptFileName) == 0)!
{!
// Error handling!
}!
processor->AddPipeline(pipeline);!
pipeline->Delete();!
vtkCPDataDescription *dataDesc = vtkCPDataDescription::New();!
dataDesc->AddInput("input");!

- dataObject: コード内部のメッシュ表現をVTKデータオブジェクトに変換したもの。変換コードは、適宜作成する必要がある!

構造格子: おおむね簡単!

非構造格子: 場合によっては面倒- SetWholeExtent()は、構造格子のみ必要
51

52

CoProcessing (4): シミュレーション・コード側の対応3

CoProcessing (5): Pythonスクリプトの書出し1

! 終了処理! 適当なデータを使って、パイプラインを作成する- Python Shellから引き続き、Sliceを作成、Apply

dataDesc->Delete();!
processor->Finalize();!
processor->Delete();!
MPI_Finalize();!

! Tools!Manage Pluginsを選択、CoProcessingPluginを選択、Load Selectedをクリック、Closeをクリック- "CoProcessing"、"Writers"メニューが追加される! パイプライン処理後のデータセットを出力する場合、パイプライン末尾に"Writer"メニューからライタを追加(無くても良い)
1. ファイル名を入力。%tは、時刻ステップで置き換えられる
2. 何ステップに1回保存するかを設定

! CoProcessing!Export Stateを選択、Continueをクリック
53

54

CoProcessing (6): Pythonスクリプトの書出し2

CoProcessing (7): Pythonスクリプトの書出し3

! 書出すパイプラインのソースを選択! 可視化画像保存の設定
1. 可視化画像を連番ファイルとして保存する場合はチェックすると、以下の入力項目が現れる

! パイプラインに名前をつける
1. 書出すパイプラインのソースを選択
2. Addをクリック!
右側のリストに追加される

4. シミュレーション・コード中のvtkCPDataDescription::AddInput()に与えた名前に合わせる(先のコード例の場合は"input")

2. ファイル形式の選択
3. ファイル名を入力。%tは、時刻ステップで置き換えられる
4. 何ステップに1回保存するかを設定
5. Doneをクリック

! Doneをクリックするとファイルダイアログが現れるので、ファイル名を付けて保存する(状況により保存されない不具合有り)! スクリプトはPythonモジュールとして読み込まれるので、Pythonモ
3. Continueをクリック

5. Continueをクリック
55

ジュールとして有効な名前を付けること
56

CoProcessing (8): 備考
! CoProcessing≒シミュレーション・コードに埋込まれたpvbatch- 相違点: Pythonスクリプトは全プロセスで実行される!

Symmetric MPI mode

! シミュレーション・コードのMPI並列実行時は、パイプライン処理もまとめ

並列動作- 案外、実行時間上は負荷にならない! シミュレーション・コードの内部データとCoProcessing入力データ間のコピーを、なるべく避ける- CoProcessing入力データは変更されないことを利用! (実行時間・メモリ使用量的に)重いフィルタは極力避け、注意深くパイプライン構築
57

まとめ! ParaViewにおけるPythonの広範な活用を概説- Python Calculator、Programmable Filter、ProgrammableSource、Python Trace、Python Macro、Python Shell、pvpython、pvbatch、CoProcessing! ParaViewのPythonスクリプティング機能は多彩- 全貌の把握、適材適所の見極めが難しい- 本講習が指針となれば幸いです59

58