論文用データの記録・再生(EMOUT_ARTICLE_MODE

article 機能は、図作成スクリプトが実際に使った最小限のグリッドデータだけを記録し、 元の巨大な EMSES シミュレーション出力なしで同じ図を再生成するための仕組みです。 論文投稿時の公開データ、補足資料、共同研究者への再現用 bundle を作る用途を想定しています。

通常の解析スクリプトはそのまま使い、環境変数または Emout() の引数で normal / record / replay を切り替えます。

いつ使うか

  • plot()to_numpy() で使ったスライスだけを公開したい。

  • Jupyter notebook や 1 本の script で作った複数 figure を 1 つの公開 bundle にまとめたい。

  • 複数の simulation output を比較する図を、別環境でも再現できる形で保存したい。

  • plasma.inp / plasma.toml / 境界メッシュ / 小さな診断ファイルも含めて再現したい。

particle データ、backtrace、remote execution そのものは article replay bundle には含まれません。 replay は「記録済みのグリッドスライスと入力メタデータから図を再生成する」用途に絞られています。

クイックスタート

図作成スクリプトは通常どおり書きます。スライスの軸順序は (t, z, y, x) です。

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()

同じスクリプトを、環境変数で record / replay に切り替えます。

# Normal run
python figure.py

# Record article data
EMOUT_ARTICLE_MODE=record \
EMOUT_ARTICLE_RECORDS_PATH=article-records \
python figure.py

# Replay from recorded article data
EMOUT_ARTICLE_MODE=replay \
EMOUT_ARTICLE_RECORDS_PATH=article-records \
python figure.py

引数で明示することもできます。

data = emout.Emout(
    "output_dir",
    article_mode="record",
    article_records_path="article-records",
)

保存されるもの

基本的な保存対象

record mode では、plot()to_numpy() が materialize したデータだけを保存します。 例えば data.phisp[-1, :, ymid, :].plot() は、その 2D スライスだけを data.h5 に保存します。 同じ field と selector が複数回使われても、重複して保存されません。

公開データを小さくする

Data3d.plot_surfaces() は 3D field を使うため、そのままでは公開データが大きくなりがちです。 article record mode では bounds が渡された場合、data.phisp[-1].plot_surfaces(..., bounds=bounds) のような呼び出しを検出し、描画範囲に 1 grid padding を加えた 3D ROI だけを保存します。 保存済み ROI は元の global 座標に合わせて replay されるため、境界メッシュや mask surface との位置関係は保たれます。 bounds を渡さない場合、必要範囲を判断できないため 3D 全体が保存対象になります。

時間平均も公開データ用に記録できます。data.phisp[-20:].mean() は time axis の lazy reduction として扱われ、 平均に使った 20 timestep をそのまま保存するのではなく、平均後のデータだけを保存します。 plot_surfaces(..., bounds=bounds) に接続した場合は、bounds 周辺の ROI だけを各 timestep から読み、 平均後 ROI を保存します。

field = data.phisp[-20:].mean()
field.plot_surfaces(data.boundaries, bounds=bounds, mode="cmap")

mean() が返す field からも field.inpfield.unitfield.boundaries を参照できます。 そのため、図作成関数が data.inpdata.boundaries を読む場合でも、平均 field を渡して同じ構造で使えます。

bundle に含まれるファイル

ファイル

内容

用途

manifest.json

記録した field、selector、shape、slice axes、単位情報

replay 時に requested slice と保存済み slice を照合する

data.h5

記録済みの NumPy 配列

Data1d / Data2d / Data3d として再構築する

source.json

元 simulation path、basename、recorded files の hash

別環境で source を対応付け、改変を検出する

plasma.inp

入力ファイル

data.inp、単位変換、境界メッシュ再構築

plasma.toml

TOML 入力ファイル

data.toml の再現

icur, ocur, pbody

小さな診断ファイル(存在する場合)

data.icur / data.ocur / data.pbody の再現

data.h5 内の dataset は HDF5 gzip 圧縮で保存されます。replay 側では HDF5 が透過的に展開するため、 通常の plot() / to_numpy() の使い方は変わりません。

ディレクトリ構造

基本構造は records-path/datasets/<source>/<article-name>/ です。 article_name を省略すると default になります。

article-records/
└── datasets/
    └── output_dir-012345abcd/
        ├── source.json
        └── default/
            ├── manifest.json
            ├── data.h5
            ├── plasma.inp
            ├── plasma.toml
            ├── icur
            ├── ocur
            └── pbody

<source> は通常、source directory の basename と絶対パス hash から作られます。 別環境では絶対パスが変わるため、replay はまず <source> の直接一致を試し、 見つからない場合は source.json の basename で対応付けます。

複数 figure と複数 simulation

EMOUT_ARTICLE_NAME を指定すると、fig1fig2 のように figure ごとに分けられます。 指定しない場合は default にまとまるため、notebook や 1 本の script で作るすべての figure を 1 つの bundle にできます。

EMOUT_ARTICLE_MODE=record \
EMOUT_ARTICLE_RECORDS_PATH=article-records \
EMOUT_ARTICLE_NAME=fig1 \
python figure.py

同じ article_nameEmout() を作り直すと、既存 bundle に未記録スライスだけを追記します。 Jupyter のセル再実行や、関数内で Emout() を作り直す script でも同じ bundle を使えます。

複数の simulation output を扱う場合は source ごとに保存先が分かれます。 同じ basename の output が複数ある場合は、公開先でも同じ source を選べるように 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 / replay の両方で同じ article_source_name を使うと、絶対パスが変わっても article-records/datasets/case_a/default/ のような安定した保存先を使えます。

replay でできること

replay mode の emout.Emout() は、元の HDF5 出力ではなく記録済み bundle を読む proxy を返します。 記録済みスライスであれば、通常の Data と同じように plot()to_numpy() が使えます。

data = emout.Emout(
    "output_dir",
    article_mode="replay",
    article_records_path="article-records",
)

data.phisp[-1, :, ymid, :].plot()
arr = data.ex[-1, :, ymid, :].to_numpy()

vector alias も、必要な component が記録されていれば使えます。

data.exz[-1, :, ymid, :].plot()

入力メタデータと境界も replay できます。

data.boundaries.plot()
data.phisp[-1].plot_surfaces(data.boundaries, bounds=bounds)
icur = data.icur
ocur = data.ocur
pbody = data.pbody

未記録のスライスにアクセスすると例外になります。これは公開 bundle に図の再現に必要なデータが 含まれているかを確認するための挙動です。

archive 形式

article_archive を有効にすると、各 bundle を archive として自動保存します。

data = emout.Emout(
    "output_dir",
    article_mode="record",
    article_records_path="article-records",
    article_archive="zip",
)
EMOUT_ARTICLE_MODE=record \
EMOUT_ARTICLE_RECORDS_PATH=article-records \
EMOUT_ARTICLE_ARCHIVE=zip \
python figure.py

指定

作成される archive

article_archive=True / EMOUT_ARTICLE_ARCHIVE=1

<article-name>.tar.gz

article_archive="tar.gz" / EMOUT_ARTICLE_ARCHIVE=tar.gz

<article-name>.tar.gz

article_archive="zip" / EMOUT_ARTICLE_ARCHIVE=zip

<article-name>.zip

replay 時は展開済み directory がなくても、対応する .tar.gz または .zip があれば自動展開します。 zip はアップロード先が .tar.gz を受け付けない場合や、Windows で展開しやすい形式にしたい場合に便利です。

設定一覧

引数

環境変数

既定値

意味

article_mode

EMOUT_ARTICLE_MODE

normal

normal / record / replay を切り替える

article_records_path / records_path

EMOUT_ARTICLE_RECORDS_PATH / EMOUT_RECORDS_PATH

なし

bundle の root directory

article_name

EMOUT_ARTICLE_NAME

default

figure や notebook 単位の bundle 名

article_source_name

EMOUT_ARTICLE_SOURCE_NAME

なし

複数 source を別環境でも安定して識別する名前

article_archive

EMOUT_ARTICLE_ARCHIVE

なし

tar.gz または zip archive を作成する

よくあるハマりどころ

  • record / replay では article_records_path が必須です。環境変数または引数で指定してください。

  • 複数 source が同じ basename(例: case_a/output, case_b/output)を持つ場合は、article_source_name を指定してください。

  • np.asarray(data.phisp[...]) よりも data.phisp[...].to_numpy() を使うと、記録対象であることが明示されます。

  • plot_surfaces() で公開データを小さくしたい場合は bounds を渡してください。data.phisp[-1, :, ymid, :] のような 2D slice はそのまま 2D として保存されますが、data.phisp[-1] のような 3D selection は bounds なしでは 3D 全体になり得ます。

  • data.phisp[-20:].mean() の既定は time axis 平均です。空間方向を平均したい場合は、意図が分かるように mean(axis="x") などを明示してください。

  • record mode の remote rendering では worker 側で使った slice が記録されます。replay では particle、backtrace、remote execution は提供されません。必要なら元データで実行してから、可視化に使うグリッドスライスを record してください。

  • 元 script がランダムな描画設定や外部ファイルに依存する場合、article bundle だけでは完全再現できません。図作成 script も一緒に公開してください。

関連クラス

詳細なシグネチャは API リファレンス(emout.articleemout.core.facade)を参照してください。

  • emout.Emoutarticle_mode / article_records_path / article_name などの公開入口

  • ArticleRecorder — record mode で slice、metadata、archive を保存する内部クラス

  • ArticleReplayEmout — replay mode で記録済み bundle を読む proxy