3. Pythonスクリプトのバッチ処理

Pythonスクリプトは、ParaView の中で2つの方法で活用することができます。第一に、Pythonスクリプトは、GUIでのユーザーと同じアクションを実行することで、可視化のセットアップと実行を自動化することができます。第二に、Pythonスクリプトはパイプラインオブジェクトの内部で実行され、それによって並列可視化アルゴリズムを実行することができます。本章では、第一のモードであるバッチスクリプトによる可視化の自動化について説明します。

バッチスクリプトは、平凡な作業や反復作業を自動化するのに適した方法ですが、GUIが望ましくない、あるいは使用できない状況で ParaView を使用する場合にも重要な要素になります。Pythonスクリプトの自動化により、スケーラブルな並列ポスト処理フレームワークとして ParaView を活用することができるようになります。また、Pythonスクリプトを活用して、シミュレーションコード内に in situ 計算を確立しています。(ParaViewCatalyst という in situ ライブラリをサポートしており、このチュートリアルの 4.10 章 にドキュメントがあり、より詳細な情報は https://www.paraview.org/in-situ/ でオンライン公開されています)。

このチュートリアルは、Pythonスクリプトの簡単な紹介に過ぎません。スクリプトに関するより包括的なドキュメントは、ParaView ユーザーズガイドに記載されています。また、ParaView のドキュメントページ (https://www.paraview.org/documentation) には、ParaView のPython APIへの完全なリファレンスを含む、さらなるリンクが用意されています。

3.1. Pythonインタプリタの起動

Pythonインタプリタを呼び出すには、多くの方法があります。使用する方法は、スクリプトをどのように使用するかに依存します。Pythonインタプリタを呼び出す最も簡単な方法、そしてこのチュートリアルで使用する方法は、メニューからView → Python Shellを選択することです。これにより、ParaView のPythonシェルのためのコントロールを含むダイアログボックスが表示されます。これはPythonのインタプリタであり、後述するコマンドによって|ParaView| を直接制御することができます。入力に便利なように、ParaView のPythonシェルは、上下キーによるタブ補完と履歴のブラウジングをサポートしています。

../../_images/PythonShellDialog.png

スクリプトを書くことに興味がある方は、スクリプトを呼び出す他の方法の説明を飛ばして、次節に進んでください。

ParaView には、Pythonスクリプトを実行する2つのコマンドラインプログラムが付属しています。pvpythonpvbatch です。これらは Python ディストリビューションに付属する python 実行ファイルに似ており、コマンドラインまたはファイルから Python スクリプトを受け取り、そのスクリプトを Python インタプリタに送ります。

pvpythonpvbatch の違いは微妙で、可視化サービスを確立する方法と関係があります。pvpython は、GUIをPythonインタプリタに置き換えた paraview クライアントGUIとほぼ同じものです。これは、ParaView サーバーに接続するシリアルアプリケーションです(ビルトインでもリモートでも可能です)。pvbatch は、コマンドが ParaView クライアントへのソケット接続からではなく、Pythonスクリプトから取得されることを除いて、pvserver とほぼ同じです。これは並列アプリケーションで、(MPIでコンパイルされていると仮定して) mpirun で起動することができますが、他のサーバーに接続することができません。一般的には、インタプリタを対話的に使用する場合は pvpython を使用し、並列で実行する場合は pvbatch を使用する必要があります。

また、ParaView の外側のプログラムから ParaView Python モジュールを使用することも可能です。これは、環境変数 PYTHONPATHParaView ライブラリと Python モジュールの場所を指定し、環境変数 LD_LIBRARY_PATH (on Unix/Linux), DYLD_LIBRARY_PATH (on Mac), または PATH (on Windows) に ParaView ライブラリを指定すれば行うことが出来ます。この方法でPythonスクリプトを実行すると、Python's Integrated Development and Learning Environment (IDLE) のようなサードパーティアプリケーションを利用することができるようになります。環境設定の詳細については、ParaView Wikiを参照してください。

3.2. ParaViewの状態をトレースする

Pythonスクリプト機能の奥深さに飛び込む前に、Pythonスクリプトを作成するための自動化された機能を少し探ってみましょう。ParaView GUI の Python Trace 機能を使うと、多くの一般的なタスクのための Python スクリプトを非常に簡単に作成することができます。トレースを使用するには、ツールメニューにある Start Trace でトレース記録を開始し、同じくツールメニューにある Stop Trace でトレース記録を終了するだけです。これは、GUIで行われたアクションを再構築するPythonスクリプトを生成します。このスクリプトには、これから説明する一連の操作と同じものが含まれています。このように、トレース記録は Python インターフェースでどのようにアクションを行うかを理解しようとするときに良いリソースとなり、逆に以下の説明は任意のトレーススクリプトの内容を理解するのに役立ちます。

Exercise 3.1 (Creating a Python Script Trace)

もし前節の演習に続けて行っているのであれば、今が ParaView をリセットする良い機会です。これを行う最も簡単な方法は、メニューから Edit → Reset Session を選択するか、ツールバーの pqResetSession を押すことです。

  1. ツールメニューのStart Traceオプションをクリックします。

  2. トレースに関するオプションのダイアログボックスが表示されます。これらのオプションの意味については、後ほど説明します。とりあえず、OKをクリックしてください。

  3. メインの ParaView GUIで簡単なパイプラインを構築します。例えば、球体のソースを作成し、それをクリップします。

  4. ツールメニューのStop Traceをクリックします。

  5. 編集ウィンドウが開き、先ほど作成した操作を再現するPythonスクリプトが表示されます。

たとえParaViewのPythonバインディングに触れたことがなくても、トレースされたスクリプトで実行されるコマンドは見慣れたものになるはずです。ハードディスクに保存されたら、もちろんお気に入りのエディタでスクリプトを編集することができます。最終的なスクリプトは、pvpython または pvbatch プログラムによって解釈され、完全に自動化された可視化を行うことができます。また、このスクリプトをGUIで実行することも可能です。Python Shellダイアログには保存されたスクリプトを呼び出すRun Scriptボタンがあります。

アクションをトレースすることなく、現在の ParaView 状態をPythonスクリプトとしてキャプチャする方法もあります。単に ParaView File メニューから Save State... を選び、(ParaView .pvsm state file とは対照的に) Python .py state file として保存するよう選択するだけです。ステートPythonスクリプトの演習は行いませんが、トレースされたPythonスクリプトとほぼ同じ方法で使用できると言えば十分でしょう。この機能については、自由に試してみてください。

../../_images/TraceOptions.png

演習で先に述べたように、Python のトレースにはいくつかのオプションがあり、トレース開始前にダイアログボックスで表示されます。最初のオプションは、トレースに保存されるプロパティを選択します。いくつかのプロパティは、GUIウィジェットに入力された値のように、GUIを通して明示的に設定するものです。いくつかのプロパティは、適用されているオブジェクトの境界に基づいてクリップ平面の初期位置のように、ParaView アプリケーションによって内部的に設定されます。他の多くのプロパティは、何らかのデフォルト値のままになっている。保存するプロパティは、以下のクラスのいずれかを選択することができます。

all properties

すべてのプロパティの値を、たとえデフォルトのままであってもトレースします。これは、すべての可能なプロパティを把握するため、または他のユーザーの設定に関係なく一貫した状態を確保するために有用です。また、これは非常に冗長な出力となり、読むのが大変な場合があります。

any *modified* properties

デフォルトから変更されないプロパティは無視されます。これは、ほとんどのユースケースで有効なオプションです。

only *user-modified* properties

ユーザーによって明示的に設定されていないプロパティは無視されます。この性質のトレースは、内部で設定されたプロパティがスクリプトの実行時に再適用されることに依存します。

次のオプションは、サーバーの状態ではなく、ParaView GUI(またはクライアント)で管理される補足的なオブジェクトに関係する。このボックスをチェックすると、これらのオブジェクトに関連するすべての状態(カラーマップ、カラーバー、その他の注釈を含む)を取り込むことができます。

最後に、ParaView には、生成中のトレースファイルを表示するオプションがあります。これは、ParaView のGUIで特定のアクションを再現するためにどのようなPythonコマンドが使えるかを学ぶときに役立つオプションです。

3.3. マクロ

ParaView の動作をカスタマイズする簡単で強力な方法は、あなたのPythonスクリプトを マクロ として追加することです。マクロとは、ツールバーのボタンやメニューバーのエントリから呼び出すことができる自動化されたスクリプトのことです。どのようなPythonスクリプトもマクロに割り当てることができます。

Exercise 3.2 (Adding a Macro)

この演習は Exercise 3.1 の続きです。この演習を始める前に、その演習を終了しておく必要があります。numref:CreatingAPythonScriptTrace で作成した Python スクリプトを含む編集ウィンドウを開いておく必要があります。

  1. 編集ウィンドウのメニューバーから、File → Save As Macro...を選択します。

  2. マクロファイルにわかりやすい名前をつけて、ブラウザが提供するデフォルトのディレクトリに保存します。これで、ParaView GUI の上部にあるマクロツールバーにマクロが表示されるはずです。

この時点で、マクロがツールバーに追加されているのが確認できるはずです。デフォルトでは、マクロツールバーボタンは中列の右端に配置されます。GUIにスペースがない場合、ツールバーを移動して表示する必要があるかもしれません。また、マクロがマクロメニューに追加されていることが確認できます。

  1. Pythonエディタウィンドウを閉じます。

  2. メニューのEdit → Delete Allを選択するか、ツールバーの pqResetSession を選択して、作成したパイプラインを削除してください。

  3. ツールバーのボタンをクリックするか、Macrosメニューから選択して、マクロを有効にします。

この例では、マクロがゼロから何かを作成しました。これは、あるデータを毎回同じように読み込むことが多い場合に便利です。また、既存のデータに適用されるフィルタの作成をトレースすることもできます。このようなトレースからマクロを作成すると、異なるデータに対して同じ可視化を自動化することができます。

3.4. パイプラインの作成

前の2つの節で説明したように、ParaView GUI の Python Trace 機能は、スクリプトを作成するための簡単なメカニズムを提供します。このセクションでは、ParaView スクリプトの基本的なバインディングを説明し始めます。これはPythonスクリプトを構築する上で重要な情報ですが、GUIでトレースを作成することにいつでも戻ることができます。

どのような ParaView Python スクリプトでも最初にしなければならないことは、 paraview.simple モジュールをロードすることです。これは下記を起動することで行われます。

from paraview.simple import *

一般的に、このコマンドは ParaView バッチ Python スクリプトの最初に起動される必要があります。このコマンドは、ParaView のスクリプトダイアログを表示するときに自動的に呼び出されますが、他のプログラム(pvpythonpvbatch を含む)で Python インタープリタを使用するときは、自分で追加する必要があります。

paraview.simple モジュールは、 ParaView で定義されたすべてのソース、リーダー、フィルタ、ライターに対して関数を定義しています。関数はGUIメニューに表示されているものと同じ名前になり、スペースや特殊文字が取り除かれたものになります。例えば、Sphere``関数はGUIのSources Sphereに対応し、``PlotOverLine 関数はFilters → Data Analysis → Plot Over Lineに対応する。各関数はパイプラインオブジェクトを作成し、パイプラインブラウザに表示されます(ライターを除く)。また、そのパイプラインオブジェクトのプロパティを照会して操作するために使用できる proxy となるオブジェクトが返されます。

また、 paraview.simple モジュールには、他の操作を行うための関数もいくつか用意されています。例えば、 ShowHide という2つの関数は、それぞれビュー内のパイプラインオブジェクトの表示設定をオン・オフするものです。Render 関数は、ビューを再描画します。

paraview.simple`` で使用できる関数の簡潔なリストを得るには、 dir(paraview.simple) を実行してください。また、 3.6 章 で説明したように、 help(paraview.simple) で詳細なリストを表示することもできます。

Exercise 3.3 (Creating and Showing a Source)

もし前節の演習に続けて行っているのであれば、今が ParaView をリセットする良い機会です。これを行う最も簡単な方法は、ツールバーから pqResetSession を選択することです。

まだの方は、メニューのView → Python Shellを選択して、ParaView GUIでPythonシェルを開いてください。すでに以下のように追加されていることに気がつくでしょう。

from paraview.simple import *

Pythonシェルで次のように入力して、Sphereソースを作成し、表示します。

sphere = Sphere()
Show()
Render()
ResetCamera()

Sphere コマンドは球体のパイプラインオブジェクトを作成します。実行すると、パイプラインブラウザにアイテムが作成されるのが確認できます。パイプラインオブジェクトへのプロキシを変数 sphere に保存します。この変数は(まだ)使用していませんが、パイプラインオブジェクトへの参照を保存しておくことは良い習慣です。

続く Show コマンドはこのオブジェクトを表示するようにし、 Render コマンドはその結果を表示するようにします。最後に、ParaView GUIでは初めて表示されるデータに対して自動的にカメラが調整されますが、Pythonスクリプトでは調整されません。ResetCamera の呼び出しは、必要に応じてこの自動的なカメラ調整を実行します。

この時点で、再びGUIと直接対話することができます。マウスでビューのカメラアングルを変えてみてください。

Exercise 3.4 (Creating and Showing a Filter)

フィルタの作成は、ソースの作成とほとんど同じです。デフォルトでは、GUIでフィルタを作成するときと同様に、最後に作成したパイプラインオブジェクトが新しく作成するフィルタの入力として設定されます。

この演習は Exercise 3.3 の続きです。この演習を始める前に、その演習を終了しておく必要があります。

Pythonシェルで以下のスクリプトを入力し、球体を隠し、球体にシュリンクフィルタを追加し、それを表示します。

Hide()
shrink = Shrink()
Show()
Render()

球体は Shrink フィルタの出力に置き換えられます。このフィルタはすべてのポリゴンを小さくして、メッシュが分解されたような外観を与えます。

これまで、パイプラインを構築する際には、パイプラインオブジェクトのデフォルトのパラメータを受け入れてきました。 2 章 の演習で見てきたように、プロパティパネルを使ってオブジェクトのパラメータを変更しなければならないことはよくあることです。

Pythonスクリプトでは、作成関数から返される proxy を用いて、パイプラインオブジェクトを操作します。これらのプロキシは、実際には、プロパティパネルで設定したのと同じプロパティに対応するクラス属性を持つPythonオブジェクトです。プロパティパネルで設定したものと同じ名前を持ち、スペースやその他の不正な文字は削除されます。dir(variable)help(variable) を使って、アクセス可能なすべての変数の属性のリストを得ることができます。ほとんどの場合、オブジェクトの属性を変更するためには、単に値を代入するだけです。

Exercise 3.5 (Changing Pipeline Object Properties)

この演習は Exercise 3.3Exercise 3.4 からの続きです。この演習を始める前に、それらの演習を終了しておく必要があります。

これまで、対応するパイプラインオブジェクトのプロキシである sphereshrink という2つのPython変数を作成したことを思い出してください。まず、Pythonシェルに以下のコマンドを入力すると、sphereのすべての属性の簡潔なリストが表示されます。

dir(sphere)

次に、Pythonシェルに以下のコマンドを入力し、球体のTheta Resolutionプロパティの現在値を取得します。

print(sphere.ThetaResolution)

Python インタープリタは 8 という結果で応答するはずです。(Pythonに引数を標準出力するように指示する print 関数は、Pythonシェルがどのコマンドの結果も出力するため、ここでは不要であることに注意してください)。この性質を利用して、球の赤道付近のポリゴンの数を2倍にしてみましょう。

sphere.ThetaResolution = 16
Render()

Shrinkフィルタは、Shrink Factorというプロパティしか持っていません。この係数を調整することで、ポリゴンの大きさを大きくしたり小さくしたりすることができます。ここでは、ポリゴンを小さくするように係数を変更してみましょう。

shrink.ShrinkFactor = 0.25
Render()

Pythonコマンドを入力してパイプラインオブジェクトのプロパティを変更すると、それに応じてプロパティパネルのGUIが更新されることにお気づきかもしれません。

ここまでは、分岐しないパイプラインのみを作成してきました。これは単純でよくあるケースで、 paraview.simple モジュールの他の多くのものと同様に、単純でよくあるケースの作業量を最小限に抑えつつ、より複雑なケースへの道筋を明確にするために設計されています。分岐しないパイプラインを構築したため、ParaView はフィルタ入力を前に作成したオブジェクトに自動的に接続し、スクリプトが一連の操作のように読めるようにしました。しかし、パイプラインに分岐がある場合、フィルタ入力をより具体的にする必要があります。

Exercise 3.6 (Branching Pipelines)

この演習は Exercise 3.3 から Exercise 3.5 までの続きになります。この演習を始める前に Exercise 3.3Exercise 3.4 を終了する必要があります( Exercise 3.5 はオプションです)。

ここまでで、2つのPython変数 sphereshrink を作成しましたが、これらは対応するパイプラインオブジェクトのプロキシであることを思い出してください。ここでは、sphereソースからワイヤーフレームを抽出するために、2つ目のフィルタを追加していきます。Python シェルで次のように入力します。

wireframe = ExtractEdges(Input=sphere)
Show()
Render()

球体のソースに Extract Edges フィルタを追加します。これで、元の球体のワイヤーフレームと縮小されたポリゴンの両方が見えるはずです。

ExtractEdges 関数の引数として Input=sphere を指定し、Extract Edges フィルタの入力を明示的に設定していることに注意してください。これは、オブジェクトを作成する際に Input プロパティを設定していることになります。デフォルトの入力でオブジェクトを作成し、後で入力を設定することも可能ですが、これはお勧めできません。問題は、すべてのフィルタがすべての入力を受け入れるわけではないことです。もし、最初に間違った入力でフィルタを作成した場合、 Input プロパティを正しい入力に変更する前にエラーメッセージが表示される可能性があります。

球体のソースがその出力に2つのフィルタを接続しているのは、パイプラインにおける fan out の一例です。1つの出力に複数のフィルタを接続することは常に可能です。すべてのフィルタではありませんが、いくつかのフィルタは、入力に複数のフィルタを接続することができます。複数のフィルタが入力に接続されることは、fan in と呼ばれます。ParaView のPythonスクリプトでは、ファンインはファンアウトと同じように、フィルタの入力を明示的に定義することで処理されます。複数の入力を(1つのポートに)設定する場合は、単に入力を1つではなく、パイプラインオブジェクトのリストに設定します。

Did you know?

ResampleWithDataset のように、複数の入力ポートを持つフィルタでは、入力プロパティを区別するために別の名前を使用します。ポート名は一般的に InputSource と呼ばれますが、確かなことは Tracehelp で確認してください。

例えば、Group Datasetsフィルタを使って、shrinkとextract edgesフィルタの結果をグループ化してみましょう。Pythonシェルで以下の行を入力します。

group = GroupDatasets(Input=[shrink, wireframe])
Show()

これで shrink と extract edges フィルタを表示する理由がなくなったので、非表示にしてみましょう。デフォルトでは、 ShowHide 関数は最後に作成されたパイプラインオブジェクトに対して動作します ( フィルタを作成する際のデフォルト入力と同じです )。しかし、引数としてオブジェクトを与えることで、明示的に選択することができます。shrink と extract edges フィルタを隠すには、Python シェルで次のように入力します。

Hide(shrink)
Hide(wireframe)
Render()

前回の演習では、creator関数の引数に Input=({input object}) を指定することで、 Input プロパティを設定できることを確認しました。一般的には、オブジェクトの作成時に {プロパティ名}={プロパティ値} を指定することで、任意のプロパティを設定することができます。例えば、以下のように球体を線で結ぶと、 Theta ResolutionPhi Resolution の両方を設定することができます。

sphere = Sphere(ThetaResolution=360, PhiResolution=180)

3.5. Active Objects

もし、ParaView GUI を使用したことがあるなら、アクティブオブジェクトの概念に既に精通しているはずです。GUI内で可視化を構築し、操作する際には、まずパイプラインブラウザでオブジェクトを選択する必要があります。プロパティパネルなどの他の GUI パネルは、アクティブなオブジェクトが何であるかに基づいて変更されます。アクティブなオブジェクトは、フィルタの追加など、いくつかの操作で使用するデフォルトのオブジェクトとしても使用されます。

Pythonのバッチスクリプトは、アクティブオブジェクトの概念も理解しています。実際、一緒に実行すると、GUIとPythonインタプリタは同じアクティブオブジェクトを共有します。前節でフィルタを作成したとき、そのフィルタに与えられたデフォルトの入力は、実は アクティブオブジェクトでした。新しいパイプラインオブジェクトを作成すると、その新しいオブジェクトがアクティブになりました(GUIでオブジェクトを作成したときと同じです)。

アクティブオブジェクトの取得と設定は、それぞれ GetActiveSourceSetActiveSource 関数で行うことができます。また、 GetSources 関数を使用すると、すべてのパイプラインオブジェクトのリストを取得することができます。GUI のパイプラインブラウザで新しいオブジェクトをクリックすると、Python のアクティブオブジェクトが変更されます。同様に、Pythonで SetActiveSource を呼び出すと、パイプラインブラウザで対応するエントリがハイライト表示されるのがわかります。

Exercise 3.7 (Experiment with Active Pipeline Objects)

この演習は、前節の演習の続きです。しかし、もしあなたが望むなら、好きなパイプラインを作り、それに従うことができます。

以下のことを試して、アクティブなオブジェクトで遊んでみてください。

  • GetSources() を呼び出して、オブジェクトのリストを取得します。そのリストの中から、作成したソースとフィルタを探します。

  • GetActiveSource() を呼び出して、アクティブなオブジェクトを取得します。パイプラインブラウザで選択されているものと比較します。

  • パイプラインブラウザで何か新しいものを選択し、もう一度 GetActiveSource() を呼び出します。

  • SetActiveSource() 関数を使用して、アクティブなオブジェクトを変更します。SetActiveSource の引数には、先ほど作成したプロキシオブジェクトのいずれかを使用できます。パイプラインブラウザで変更を確認します。

アクティブなパイプラインオブジェクトを維持することに加えて、ParaView Pythonスクリプトはアクティブビューも維持します。ParaView のユーザーとして、あなたはすでに複数のビューとアクティブなビューに精通しているはずです。アクティブビューはGUI上では青いボーダーで表示されます。Pythonの関数 GetActiveViewSetActiveView を使用すると、アクティブビューを照会したり変更したりすることができます。パイプラインオブジェクトと同様に、アクティブビューはGUIとPythonインタプリタとの間で同期されます。

3.6. Online Help

このチュートリアルは、ParaView ブックやWikiにある同様の説明と同様に、Pythonのバッチスクリプトを理解し作成するために必要なキーコンセプトを提供するように設計されています。利用可能な関数、クラス、プロパティの完全なリストを含む詳細なドキュメントは、ParaView ビルドプロセスによって維持され、ParaView アプリケーション内からオンラインヘルプとして提供されています。このようにして、私たちは、あなたが使っている ParaView のどのバージョンに対しても、ドキュメントが最新であること、そして簡単にアクセスできることを保証することができるのです。

ParaView Pythonバインディングは help ビルトイン関数を使用します。この関数は任意のPythonオブジェクトを引数として取り、それに関するドキュメントを返します。例えば、次のようにタイプします。

help(paraview.simple)

は、モジュールの簡単な説明と、そのモジュールに含まれる全機能のリストと、それぞれの機能の簡単な概要を返します。例えば

help(Sphere)
sphere = Sphere()
help(sphere)

は、まず Sphere 関数についてのヘルプを提供し、次にそれを使ってオブジェクトを作成し、そして返されたオブジェクトについてのヘルプを提供します(プロキシのすべてのプロパティのリストも含みます)。

プロパティパネルのプロパティグループに表示されるウィジェットのほとんどは、Pythonのクラスを構築するのと同じイントロスペクションから自動的に生成されます。(使い勝手を良くするためにカスタムパネルが作成された例外はごく一部です)。したがって、プロパティパネルでラベル付けされたウィジェットを見た場合、Pythonオブジェクトに同じ名前で対応するプロパティが存在する可能性が高いです。

GUIにパイプラインオブジェクトのカスタムパネルがあるかどうかにかかわらず、GUIのオンラインヘルプからそのオブジェクトのプロパティに関する情報を取得することができます。いつものように、ツールバーの pqHelp ボタンでヘルプを表示させます。ヘルプコンテンツのSources、Filters、Readers、Writersの項目で、利用可能なすべてのパイプラインオブジェクトのドキュメントを見つけることができます。それぞれの項目には、そのタイプのオブジェクトのリストが表示されます。オブジェクトのどれかをクリックすると、Python 内から設定できるプロパティのリストが表示されます。

../../_images/ObjectHelp.png

3.7. ファイルからの読み込み

ParaView GUIでファイルを開くのと同じように、PythonスクリプトでReaderを作成することができます。リーダオブジェクトはソースやフィルタと同じように作成されます。 paraview.simple にはそれぞれのリーダタイプに対して、パイプラインオブジェクトを作成し、プロキシオブジェクトを返す関数が用意されています。以下に説明するように、与えられたリーダーを直接インスタンス化することもできますし、よりシンプルに reader = OpenDataFile({filename}) を呼び出すこともできます。

すべてのリーダーオブジェクトは、ファイル名を指定する少なくとも1つのプロパティ(GUIでは非表示)を持っています。このプロパティは慣例的に FileName または FileNames と呼ばれています。コンストラクションオブジェクトの引数に FileName={full path} のように記述して、リーダーを作成する際には常に有効なファイル名を指定する必要があります。有効なファイル名が指定されていない場合、リーダーは正しく初期化されないことがよくあります。

Exercise 3.8 (Creating a Reader)

これから新しい可視化を始めるので、これまでの演習について行ったのなら、今が ParaView をリセットする良い機会です。これを行う最も簡単な方法は、ツールバーから pqResetSession を選択することです。また、Pythonのシェルも必要です。もしまだなら、メニューから View → Python Shell で開いてください。

この演習では、Python シェルから disk_out_ref.ex2 ファイルを読み込みます。このファイルをコンピュータ上に置き、Pythonシェルにタイプまたはコピーしてください。ここでは {path}/disk_out_ref.ex2 という名前で参照します。ファイルブラウザを使って、このファイルを探すことができます。(クイックアクセスディレクトリのExamplesをクリックして、ファイルブラウザの表示位置を確認してください。このファイルの一般的なパスは次のとおりです。

Mac
/Applications/ParaView-x.x.x.app/Contents/examples

Windows

C:/Program Files/ParaView x.x.x/examples

Linux

/usr/local/lib/paraview-x.x.x/examples

Pythonのシェルで次のように入力し、ファイル名を指定しながらリーダーを作成します。

reader = OpenDataFile('{path}/disk_out_ref.ex2')
Show()
Render()
ResetCamera()

3.8. フィールド属性を問い合わせる

パイプラインオブジェクトのプロキシは、そのクラス固有のプロパティに加えて、共通のプロパティとメソッドを持ちます。その中でも重要なのが、 PointDataCellData プロパティです。これらのプロパティは、Python の連想配列の一種である dictionaries のように動作し、変数名 (文字列) をフィールドの特徴を保持する ArrayInformation オブジェクトにマップします。特に注目すべきは ArrayInformation メソッド GetName で、これはフィールドの名前を返します。 GetNumberOfComponents は各フィールド値のサイズ (スカラーなら 1、ベクトルならもっと) を返し、 GetRange は特定のコンポーネントに対する最小値と最大値を返します。

Exercise 3.9 (Getting Field Information)

この演習は Exercise 3.8 の続きです。この演習を始める前に、その演習を終了しておく必要があります。

まず始めに、ポイントデータのハンドルを取得し、利用可能なすべてのポイントフィールドをプリントアウトします。

pd = reader.PointData
print(pd.keys())

“pres” と “v” のフィールドに関する情報を取得します。

print(pd["pres"].GetNumberOfComponents())
print(pd["pres"].GetRange())
print(pd["v"].GetNumberOfComponents())

さて、もっと大胆にいきましょう。Pythonの for 構造体を使って、すべての配列に対して反復処理を行い、すべてのコンポーネントの範囲を表示します。

for ai in pd.values():
   print(ai.GetName(), ai.GetNumberOfComponents(), end=" ")
   for i in range(ai.GetNumberOfComponents()):
      print(ai.GetRange(i), end=" ")
   print()

3.9. Representations

パイプラインオブジェクトのデータとビューの間の “接着剤” となるのがレプレゼンテーションです。レプレゼンテーションは、データセットがビューにどのように描画されるかを管理する役割を担っています。レプリゼンテーションは、データの描画に使用される基本的なレンダリングオブジェクトと、カラーリングやライティングなどのレンダリングプロパティを定義し、管理します。GUIのDisplayグループで利用可能なパラメータは、Representationによって管理されます。パイプライン-オブジェクト-ビューのペアごとに、個別の表現オブジェクトのインスタンスがあります。これは、各ビューが異なるデータを表示できるようにするためです。

レプレゼンテーションはGUIによって自動的に作成されます。Pythonスクリプトでは、代わりに Show 関数で作成されます。実際、 Show はレプレゼンテーションへのプロキシを返します。そのため、ソース、フィルタ、リーダで行ったように Show の戻り値を変数に保存することができます。もし、保存を忘れても GetRepresentation 関数でいつでも取得することができます。引数を指定しない場合、この関数はアクティブなパイプラインオブジェクトとアクティブなビューのレプレゼンテーションを返します。また、パイプラインオブジェクトかビュー、またはその両方を指定することもできます。

Exercise 3.10 (Coloring Data)

この演習は Exercise 3.8 (そしてオプションで Exercise 3.9) の続きとなります。exodusファイルを開いていない場合は、この演習を始める前に Exercise 3.8 を終了しておく必要があります。

ジオメトリの色を青に変え、非常に顕著なスペキュラハイライトを与えてみましょう(つまり、本当にピカピカにするのです)。Pythonシェルに次のように入力し、表現を取得し、マテリアルプロパティを変更します。

readerRep = GetRepresentation()
readerRep.DiffuseColor = [0, 0, 1]
readerRep.SpecularColor = [1, 1, 1]
readerRep.SpecularPower = 128
readerRep.Specular = 1
Render()

ここで、GUI上でマウスを使ってカメラを回転させ、スペキュラハイライトの効果を確認します。

また、この表現を使って、フィールド変数で色分けすることもできます。フィールド変数を変更するために設定しなければならない状態は、実はかなりあります。ColorBy 関数は、フィールドの値によってメッシュを着色するためのシンプルなインターフェイスを提供します。その後、 UpdateScalarBars を呼び出すと、カラーバーのアノテーションも更新されます。Pythonシェルに次のように入力すると、“pres” フィールド変数によってメッシュに色をつけることができます。

ColorBy(readerRep, ("POINTS", "pres"))
UpdateScalarBars()
Render()

3.10. Views

描画領域やウィンドウは、 ParaView でビューと呼ばれています。リーダー、ソース、フィルタ、表現と同様に、ビューはPythonオブジェクトにラップされ、これらはスクリプトによって作成、取得、制御することができます。

ビューは通常GUIによって作成されますが、pythonではより意図的にビューを作成する必要があります。最も便利な方法は、 Render がビューを返す方法に依存することで、必要であれば最初にビューを作成することです。必要であれば、 CreateView ('{viewname}')CreateRenderView, CreateXYPlotView などで特定のビュータイプを作成することができます。また、 GetRenderViews を使用してすべてのビューのリストを取得したり、 GetActiveView を使用して現在アクティブビューにアクセスすることができます。また、 GetRenderView (最後に 's' は付かない) という関数があり、アクティブなビューがあればそれを取得し、アクティブビューがない場合は新しいビューを作成します。

ビューを作成すると、GUI のビューグループに表示されるすべてのプロパティにアクセスできるようになります。例えば、オリエンテーションウィジェットのON/OFF、背景色の変更、ライティングの変更などが簡単にできます。これらの第一レベルのプロパティの他に、ビューは、カメラ、アニメーション時間、GUIと一緒に実行されていない場合は、ビューのサイズなど、シーン全体のコントロールにアクセスすることができます。

Exercise 3.11 (Controlling the View)

この演習は Exercise 3.8 (そしてオプションとして Exercise 3.9Exercise 3.10 も)の続きです。exodusファイルを開いていない場合は、このエクササイズを始める前に Exercise 3.8 を終了しておく必要があります。

シーンの背景色を ParaView のデフォルトのグレーから、代わりに素敵なグラデーションに変更してみましょう。Pythonシェルに以下を入力し、Viewを取得して変更します。

view = GetActiveView()
view.Background = [0, 0, 0]
view.Background2 = [0, 0, 0.6]
view.UseGradientBackground = True
Render()

次に、カメラがどの位置にあるかをビューに問い合わせ、それをforループ内で動かして短いアニメーションを作ってみましょう。

x, y, z = view.CameraPosition
print(x, y, z)
for iter in range(0,10):
   x = x + 1
   y = y + 1
   z = z + 1
   view.CameraPosition = [x, y, z]
   print(x, y, z)
   Render()

3.11. 結果の保存

スクリプトの中で結果を保存することも簡単で、データとスクリプトを保存しておけば、ParaView で再現性のある可視化を簡単に作成することができます。

GUI内と同様に、ParaView で作業しているときに省きたい製品がいくつかあります。

  • フィルタが生成したデータを保存するには、 CreateWriter 関数を使用して、希望するファイル名のライターをフィルタに追加し、 UpdatePipeline メソッドを使用してライタープロキシにアップデートを行います。これは、パイプラインの要素をクリックして、File → Save Data を選択するのと同じです。

  • 画像の保存は SaveScreenshot('{path}/filename.still_extension') と入力するだけで簡単にできます。

  • ParaView がエンコーダーとコーデックにリンクされていると仮定すると、圧縮されたアニメーションを保存するには WriteAnimation('{path}/filename.animation_extension') とタイプするだけでよいでしょう。

すべての場合において、ParaView はファイル名の拡張子を使用して、作成する特定のファイルタイプを決定します。

Exercise 3.12 (Save Results)

この演習は Exercise 3.8 (そしてオプションで Exercise 3.9 から Exercise 3.11 まで)の続きです。exodusファイルを開いていない場合は、この演習を始める前に Exercise 3.8 を終了しておく必要があります。

まず、データから何かコンパクトなものを取り出すために、データを調査してみましょう。そして、その結果をカンマ区切りのファイルとして保存し、テキストエディタで見たり、他のツールにインポートしたりできるようにします。

plot = PlotOverLine()
plot.Source.Point1 = [0, 0, 0]
plot.Source.Point2 = [0, 0, 10]
writer = CreateWriter("{path}/plot.csv")
writer.UpdatePipeline()

次に、LineChartView を作成してプロットを表示し、結果のスクリーンショットを保存してみましょう。

plotView = FindViewOrCreate("MyView", viewtype="XYChartView")
Show(plot)
Render()
SaveScreenshot("{path}/plot.png")

ご覧の通り、ParaView のスクリプト・インターフェースは非常に強力で、一度基本を知り、Pythonの構文に慣れれば、かなり簡単に使いこなすことができます。このチュートリアルでは、ParaView のスクリプティング能力のより高い側面について触れただけです。Pythonスクリプトフィルタの実行方法、numpyや他のツールとの連携方法、バッチスケジューラで実行するためのスクリプトのパッケージング方法など、より詳細な情報はオンラインで確認することができます。