emout
EMSES シミュレーション出力の解析・可視化 Python ライブラリ
emout でできること:
.h5グリッド出力とplasma.inp/plasma.tomlを 1 行で読み込めるファサード- データの次元に応じて最適な表示を自動選択する 1D / 2D / 3D プロット
!!key dx=...,to_c=...ヘッダーから自動生成される EMSES ⇄ SI 単位変換(30 種以上の物理量に対応)- EMSES の finbound 境界形状を Python オブジェクトとして操作できる API
- ドキュメント: ユーザーガイド (日本語/English) | API リファレンス
- ノートブック例: 月面帯電シミュレーション結果の可視化
- Agent plugins: emout Context — Codex / Claude Code 標準の plugin marketplace で導入し、repo 外でも可視化 script 作成・改善、単位変換、
remote_figureを使う大規模可視化、トラブルシュートを agent に相談できます(導入手順)
インストール
pip install emout
# PyVista による 3D 可視化も標準インストールに含まれます
# インストール済み version と PyPI の更新確認
emout version --check-update
Dask によるリモート実行は Python 3.10 以上で自動的に有効になります(別途インストール不要)。
Agent plugins
emout の emout Context plugin は、シミュレーション出力ディレクトリや別 repo で Codex / Claude Code を起動したときにも、emout の軸順序・単位変換・可視化・remote_figure・トラブルシュートの文脈を使えるようにします。
codex plugin marketplace add Nkzono99/emout \
--ref main \
--sparse .agents/plugins \
--sparse plugins/emout-context
codex plugin add emout-context@emout
Claude Code では次のように導入します。
claude plugin marketplace add Nkzono99/emout \
--sparse .claude-plugin plugins/emout-context
claude plugin install emout-context@emout
emout CLI をインストール済みなら、Claude Code 用は emout claude install-plugin、Codex 用は emout codex install-plugin でも導入できます。詳しい導入・更新手順は plugin 導入手順 を参照してください。
クイックスタート
import emout
data = emout.Emout("output_dir")
# 最終ステップの電位を xz 平面(y=ny/2)でプロット — これだけで SI 単位付きカラーマップ
data.phisp[-1, :, data.inp.ny // 2, :].plot()
変数名は EMSES のファイル名から自動解決されます:
data.phisp # 電位 (GridDataSeries — 時系列)
data.nd1p # 種1 数密度
data.j1x # 種1 電流密度 x成分
data.j1xy # j1x + j1y 自動結合 → 2D ベクトル
data.j1xyz # 3D ベクトル
data.icur, data.ocur, data.pbody # テキスト診断出力 (.val_si で SI 変換)
スライスの軸順序は (t, z, y, x) です。
機能ガイド
各機能の詳しい使い方はユーザーガイドを参照してください。
| 機能 | できること | ガイド |
|---|---|---|
| プロット | plot() / cmap() / contour() で 1D/2D プロット |
→ プロット |
| アニメーション | gifplot() で GIF/HTML 生成、複数パネルレイアウト |
→ アニメーション |
| パラメータ | data.inp.nx, data.toml.species[0].wp |
→ パラメータ |
| 単位変換 | data.unit.v.reverse(1.0), data.phisp[-1].val_si |
→ 単位変換 |
| 境界メッシュ | data.boundaries.mesh(), plot_surfaces へのオーバーレイ |
→ 境界メッシュ |
| バックトレース | data.trace.forward(...), data.backtrace.get_probabilities(...) |
→ バックトレース |
| 3D (PyVista) | plot3d(mode="box"/"stream"/"quiver") |
→ PyVista 可視化 |
| リモート実行 | Dask Actor で計算ノードに処理を委譲、ローカルは画像だけ | → リモート実行 |
| 論文用公開データ | plot() / to_numpy() に使った最小スライスを記録・再生 |
→ 論文用データ |
代表的な使い方
プロット
data.phisp[-1, 100, :, :].plot() # 2D カラーマップ
data.phisp[-1, 100, :, :].contour() # 等高線
data.nd1p[-1, 100, :, :].plot(norm="log", vmin=1e-3) # 対数スケール
data.j1xy[-1, 100, :, :].plot() # ストリームライン
data.phisp[-1, :, 32, 32].plot() # 1D プロファイル
アニメーション
data.phisp[:, 100, :, :].gifplot() # Jupyter インライン
data.phisp[:, 100, :, :].gifplot(action="save", filename="out.gif") # GIF 保存
単位変換
data.unit.v.trans(1.0) # SI → EMSES
data.phisp[-1].val_si # 全 3D 配列を SI [V] で取得
境界メッシュ
data.boundaries[0].mesh() # 個別境界の MeshSurface3D
data.phisp[-1].plot_surfaces( # フィールド上にオーバーレイ
ax=ax, surfaces=data.boundaries,
)
粒子データ
p4 = data.p4 # 種4
p4.vx[0].val_si.to_series().hist(bins=200) # 速度分布
追加出力の結合 / 入出力パスの分離
# 継続出力の結合
data = emout.Emout("output_dir", ad="auto")
# 入力ファイルと出力ディレクトリを分離
data = emout.Emout(input_path="/path/to/plasma.toml", output_directory="output_dir")
論文用公開データの記録・再生
図作成スクリプトは通常どおり emout.Emout() から始めます。
環境変数で article mode を切り替えると、plot() と to_numpy() が消費した
最小スライスだけを records-path 以下に保存し、同じスクリプトで再生できます。
import emout
data = emout.Emout("output_dir")
ymid = data.inp.ny // 2
data.phisp[-1, :, ymid, :].plot(cmap="viridis")
arr = data.ex[-1, :, ymid, :].to_numpy()
# 通常実行
python fig1.py
# 記録: article-records/datasets/<output_dir>-<hash>/fig1/ に保存
EMOUT_ARTICLE_MODE=record \
EMOUT_ARTICLE_RECORDS_PATH=article-records \
EMOUT_ARTICLE_NAME=fig1 \
python fig1.py
# 再生: 元の巨大 HDF5 ではなく記録済みスライスから復元
EMOUT_ARTICLE_MODE=replay \
EMOUT_ARTICLE_RECORDS_PATH=article-records \
EMOUT_ARTICLE_NAME=fig1 \
python fig1.py
EMOUT_ARTICLE_NAME は省略できます。その場合は default という名前で保存されるため、
notebook や 1 本のスクリプトで作るすべての figure を 1 つの bundle にまとめられます。
同じ article_name で Emout() を作り直した場合も、既存 bundle に未記録スライスだけを
追記します。
複数の simulation output を開く場合、record は source ごとに
article-records/datasets/<source>/default/ へ分かれます。別環境で replay するときは
まず source directory の basename で対応付けます。同じ basename の output が複数ある場合は、
通常実行時から安定した article_source_name を指定してください。
data = [
emout.Emout("case_a/output", article_source_name="case_a"),
emout.Emout("case_b/output", article_source_name="case_b"),
]
record された data.h5 は HDF5 gzip 圧縮で保存されます。公開用に bundle 全体を
.tar.gz または .zip にまとめたい場合は EMOUT_ARTICLE_ARCHIVE=1
(.tar.gz)/ EMOUT_ARTICLE_ARCHIVE=zip、または article_archive=True /
article_archive="zip" を指定します。replay 時は展開済み directory がなくても、
対応する archive があれば自動で展開して読み込みます。
引数でも指定できます。
data = emout.Emout(
"output_dir",
article_mode="record",
article_records_path="article-records",
article_name="fig1",
article_archive="zip",
)
replay mode では未記録のスライスにアクセスすると例外になります。これは公開データに
図の再現に必要なデータが含まれているかを確認するためです。
plasma.inp と plasma.toml、小さな診断ファイル(icur, ocur, pbody)も保存されるため、
data.inp / data.toml / data.boundaries.plot() /
data.phisp[-1].plot_surfaces(data.boundaries) のような入力パラメータや境界メッシュに
依存する可視化も replay できます。
リモート実行 (Dask) — 実験的
HPC の計算ノードにデータ処理を委譲し、ログインノードにはプロット画像だけを返します。
新規コードでは Emout.remote() を使う explicit な書き方を推奨します。
従来の「サーバーが起動していれば自動的に remote」という挙動も、後方互換の互換モードとして当面は残しています。
# ターミナルでサーバーを起動(1 回だけ)
emout server start --partition gr20001a --memory 60G
emout server は TLS 認証を自動設定し、デフォルトでは 1 ユーザー 1 サーバーに
制限されます。追加セッションが必要な場合は
emout server start --allow-multiple --name <session> を使ってください。
ログインノードで field 配列を誤ってローカル materialize したくない場合は、
emout.disable_local_data_access() または
EMOUT_LOCAL_DATA_POLICY=remote_required を使えます。Emout(..., local_data_policy="allow") で小さいデータだけ明示的にローカル読み込みを許可できます。
import matplotlib.pyplot as plt
import emout
from emout.distributed import remote_figure, remote_scope
data = emout.Emout("output_dir").remote()
# 推奨: remote object を明示的に持つ
with remote_scope():
ymid = int(data.inp.ny // 2)
with remote_figure():
plt.figure(figsize=(18, 16))
data.phisp[-1, 180:400, ymid, :].plot()
(-data.exz[-1, 180:400, ymid, :]).plot()
plt.title("remote expression example")
# 互換モード: 既存の plot() コードもそのまま動く
local_data = emout.Emout("output_dir")
local_data.phisp[-1, :, 100, :].plot() # 2D スライスだけ転送
plt.xlabel("x [m]") # ローカル matplotlib で追記可能
# 全操作をサーバーで実行(ローカルにはPNG画像のみ)
with remote_figure():
local_data.phisp[-1, :, 100, :].plot()
plt.axhline(y=50, color="red")
plt.title("カスタムタイトル")
# CLI / バッチ実行ではファイル保存も可能
with remote_figure(savefilepath="figures/phisp.png"):
local_data.phisp[-1, :, 100, :].plot()
plt.title("saved remotely")
# 拡張子からフォーマットを推定
with remote_figure(savefilepath="figures/phisp.svg"):
local_data.phisp[-1, :, 100, :].plot()
# open/close 形式 — 既存コードへの導入が容易
from emout.distributed import RemoteFigure
rf = RemoteFigure()
rf.open()
local_data.phisp[-1, :, 100, :].plot()
rf.close()
# Jupyter セルマジック — セル先頭に書くだけ
# %load_ext emout.distributed.remote_figure
# %%remote_figure
# local_data.phisp[-1, :, 100, :].plot()
savefilepath を指定すると画像はそのまま保存されます。IPython では PNG/JPEG を
従来どおり inline 表示しつつ、CLI / バッチ実行ではローカル表示を行いません。
backtrace の重い計算もサーバーで実行し、可視化パラメータだけ変えて何度でも再描画できます。
data.backtrace.get_probabilities(...) でも data.remote().backtrace.get_probabilities(...) でも、
どちらも専用 proxy を返せるようになっています
(バックトレース API 自体の詳細は バックトレースガイド)。
複数シミュレーションの比較も可能です:
data_a = emout.Emout("/sim_a")
data_b = emout.Emout("/sim_b")
result_a = data_a.backtrace.get_probabilities(...)
result_b = data_b.backtrace.get_probabilities(...)
with remote_figure(figsize=(12, 5)):
plt.subplot(1, 2, 1)
result_a.vxvz.plot()
plt.subplot(1, 2, 2)
result_b.vxvz.plot()
実験的機能(ポアソン方程式 / バックトレース)
# ポアソン方程式
from emout.utils import poisson
phi = poisson(rho, dx=dx, btypes=btypes, epsilon_0=cn.epsilon_0)
# バックトレース(要 vdist-solver-fortran)
result = data.backtrace.get_probabilities(x, y, z, vx, vy, vz, ispec=0)
result.vxvz.plot()
コントリビュート
バグ報告・機能提案・PR を歓迎します。
- バグ / 質問: GitHub Issues に再現手順を添えて投稿してください
- PR:
mainから作業ブランチを切り、pytest -qがグリーンの状態で送ってください - ドキュメント:
README.md(日本語)とREADME.en.md(英語)は対応する形で維持されています。片方を更新したらもう片方にも反映してください
開発環境のセットアップやディレクトリ構成は AGENTS.md にまとまっています。
ライセンス
リンク
Metadata
Release files for emout 2.21.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| emout-2.21.2.tar.gz | 233.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| emout-2.21.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 481.8 kB
Release files / emout-2.21.2.tar.gz
| Download URL | emout-2.21.2.tar.gz |
|---|---|
| Size | 233.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dbfd2e8cb0c526c1933eaa87daf2725e829c4bdb6ebd05832fba0ca07bc083e6
|
|
BLAKE2b-256 checksum How to use checksums |
f17d6b2113c579a633c325d77afeef5fc0881fa3f8f62a4c0c2f5efe0e1e05ff
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.25
|
Release files / emout-2.21.2-py3-none-any.whl
| Download URL | emout-2.21.2-py3-none-any.whl |
|---|---|
| Size | 248.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
71739273a6be8a343e52f37806a0895f59c9991096ef4693a167b2b175e5a366
|
|
BLAKE2b-256 checksum How to use checksums |
43be8357bd1fd7245bed4e933d5d51e32c18d5b253e40f71fde3ef33425e086b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.25
|