mcpField
A
atmospheric-science-research

atmospheric-science-research

github.com/zsy1207データ・データベース247 回インストール1 週間前に更新
リポジトリ

atmospheric-science-research について

大気科学の研究者向けに、ローカルな大気データの再現可能な解析と論文向けの図表作成を案内するスキルです。メタデータ確認、計算、作図、目視レビュー、出力、文書化を段階的に定めています。

主な機能

  1. 01メタデータを先に確認
  2. 02再現可能な解析ワークフロー
  3. 03大気診断と作図の規則
  4. 04描画結果のレビューと修正
  5. 05600 dpi の PNG・PDF 出力

活用シーン

  1. 01ローカルな大気データの解析
  2. 02診断結果から論文用図表を作成
  3. 03図表を確認し未解決リスクを記録

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/zsy1207/atmospheric-science-research --skill atmospheric-science-research

インストール後、Claude Code で/atmospheric-science-researchを入力して読み込まれたか確認します。

詳細

大気科学研究

ローカルの大気データに対して診断計算を行い、再現可能なプロジェクト内で、学術誌の掲載基準を満たす図を作成します。

ワークフロー

新しい解析では手順 1~7 を実行します。図のみを修正する場合は、パッチモードを使用します。

  1. 調査 — メタデータのみを確認します:ncdump -h、cdo sinfon、h5dump -H、または Zarr 用のメタデータのみを出力する Python のワンライナーを使用します。
  2. 計画 — 結果を変える科学的な質問だけを、推奨する回答とともに尋ねます。採用した仮定をすべて計画と README に記録します。
  3. 作成 — figN/compute_*.py、figN/plot_*.py、data_output/figN/... を使用します。依頼されない限り、既存のプロジェクトを再編成しないでください。
  4. 計算 — スクリプトは必須の CLI 引数なしで実行でき、冪等で、プロットの読み込み前に再利用可能な出力を書き出します。
  5. プロット — プロット基準に従います。
  6. レビュー — 各図が PASS または BLOCKED になるまで RR を実行します。
  7. エクスポートと文書化 — 最終ファイルをエクスポートし(プロット基準 › エクスポート)、README テンプレートに従って中国語の README.md を 1 つ作成または更新します。BLOCKED の図と未解決のリスクは、README のリスクセクションに記載します。

計算ルール

  • 速度と効率 — dask など、計算効率を向上させるパッケージやアルゴリズムを優先します。
  • 再グリッド化 — 降水量とフラックスには cdo remapcon / xesmf "conservative"、滑らかな状態変数(T、Z、u、v、q)には remapbil / "bilinear" を使用します。
  • 領域の余白 — 地図に空白の縁ができないよう、部分領域の切り出し範囲は対象境界より少なくとも 1 格子点分広げます。

プロット基準

コードのパラメーターではなく、レンダリングされた PNG を正解とします。以下のすべてのパラメーターを実際のプロジェクトと RR の指摘に合わせて設定します。目標は、一流の大気科学ジャーナルに掲載できる高品質な科学図です。

サイズとフォント

図の幅は最終的な印刷幅とします:単段組では 50~85 mm、2 段組では 105~170 mm、高さは 228 mm 未満です。フォントサイズも印刷時のサイズとします:パネル文字は 12 pt の太字、パネルの説明は 10 pt、それ以外(目盛り、ラベル、凡例、カラーバー、ベクトルキー)はすべて 8~9 pt とし、8 pt 未満にはしません。

Arial を使用し、代替フォントには Helvetica を指定します。パッチを適用する際は、プロジェクト既存のフォントを維持します。単位が正立するよう、Mathtext でも同じフォントファミリーを使用します:

plt.rcParams.update({
    "font.family": "sans-serif",
    "font.sans-serif": ["Arial", "Helvetica"],
    "mathtext.default": "regular",
    "mathtext.fontset": "custom",
    "mathtext.rm": "sans",
    "mathtext.it": "sans:italic",
    "mathtext.bf": "sans:bold",
})

Mathtext の上付き単位には、r"W m$^{-2}$"、r"m s$^{-1}$" を使用します。スラッシュ表記は使用しません。

カラーマップとレベル

塗りつぶすすべてのフィールドで、明示的な levels を使用します。カラーマップは次の許可リストからのみ選択します(RdBu_r のように、逆順の _r 版も使用できます。負の値が青になります)。許可リスト内から、変数の慣例に合った色のカラーマップを選びます:

  • 0 に意味がある符号付きフィールド(偏差、差、トレンド、回帰、相関、未処理の ω、渦度、発散、u、v、水蒸気フラックス発散、正味放射)→ 発散型:RdBu、BrBG、bwr、PuOr、PRGn、cmaps.BlueWhiteOrangeRed、cmaps.hotcold_18lev。0 をレベルに含めず、対称な levels を使用して、中央のビンが 0 をまたぎ、白になるようにします(例:±0.5、±1、…)。カラーバーの既定の等幅ビンを維持し、目盛りはレベル境界に置きます。0 自体にはラベルを付けません。
  • 偏差ではない熱波、降水量、湿度、風速のフィールド → 逐次型:plasma、YlGnBu、viridis、YlOrRd、cmaps.precip3_16lev。
  • 値が levels を超える可能性がある場合は extend="both" を使用します。一方の端が物理的に閉じている場合は "max" / "min" を使用します。
  • 比較可能なパネルでは levels、cmap、extend を共通にします(pcolormesh には、cmap = plt.get_cmap(name) としたうえで、BoundaryNorm(levels, cmap.N, extend="both") を 1 つ使用します)。パネルごとの自動スケーリングはしません。領域の知見に基づいてレベルを設定し、信号が見えにくい、または飽和している場合は、範囲を確認して再設定します。
  • カラーバー:地図の下に水平配置し、単独の地図または右側の共通バーには垂直配置します。細くし(aspect は 25~40)、パネルグループより長くならないようにし、目盛りを少数にして、単位付きの短いラベルを付けます。変数とスケールごとに共通カラーバーを 1 つ使用します。
レイアウトとパネル
  • 図は必ず dpi=600, layout="constrained" を指定して作成し、ベクターキーがエクスポート解像度で測定されるようにします。3つ以上のパネルや共有カラーバーには、その中で GridSpec / subplot_mosaic を使用します。GeoAxes にカラーバーを追加した後は、間隔を再確認します。
  • パネル文字:各パネルの枠の上、左上に小文字の太字 a、b、c を置きます:ax.text(0, 1.02, "a", transform=ax.transAxes, ha="left", va="bottom", fontweight="bold")。
  • パネルの説明:6語以下の名詞句(850 hPa wind、El Niño composite など)を中央に置きます:ax.text(0.5, 1.02, "850 hPa wind", transform=ax.transAxes, ha="center", va="bottom")。文字、説明、ベクターキーは各行で同じ y 座標に揃えます。
  • suptitle、図のキャプション、デフォルトの軸タイトル、データスタンプ、図内の説明文は使用しません。解釈はキャプションまたは README に記載します。
地図
地域投影法
全球または太平洋中心PlateCarree(central_longitude=180) または Robinson
熱帯・中緯度の地域PlateCarree(デフォルト)。妥当な理由がある場合は中緯度に LambertConformal
極域NorthPolarStereo / SouthPolarStereo
  • データ描画関数(contourf、contour、pcolormesh、curly_vector、scatter)には transform=ccrs.PlateCarree() を指定します。指定しないと、座標は投影法固有の単位として読み込まれ、データ場が気づかないうちに誤った位置に描画されます。add_geometries には crs=ccrs.PlateCarree() を、パネルのテキストには transform=ax.transAxes を指定します。
  • 全球データ場には周期点が必要です:
    from cartopy.util import add_cyclic
    cyc, cyc_lon = add_cyclic(da.values, x=da["lon"].values, axis=-1)
    
  • 0°または180°をまたぐ領域では、部分領域を抽出する前に、assign_coords を使って経度を−180~180((da.lon + 180) % 360 - 180)または0~360(da.lon % 360)に変換し、その後 sortby("lon") を実行します。余白を加えるだけでは継ぎ目を閉じられません。
  • ax.coastlines(linewidth=0.8, color="0.2") を使用します。科学的に必要な場合を除き、国境は表示しません。
  • gl = ax.gridlines(draw_labels=True, linestyle="--", linewidth=0.6, color="0.5", alpha=0.6) を使用します。gl.top_labels = gl.right_labels = False とします。複数パネルの地図では、左列と最下行だけにラベルを表示します:gl.left_labels = col == 0; gl.bottom_labels = row == nrows - 1。
  • 調査領域の枠は、赤または青の破線で、linewidth は1.2~2.0、高い zorder にします。
チベット高原のマスキング

チベット高原を含む地図で、700 hPa以下(700/850/925/1000 hPa)の場合は、regionmask を使って高原上のベクター、等値線、有意性を示すドットをマスクし、塗りつぶしのデータ場は全体を表示して、その上に灰色のポリゴンを描画します。ポリゴンのデフォルトの zorder(1.5)は塗りつぶしより上に配置されるため、白い縁取りは表示されません。

from pathlib import Path
import geopandas as gpd, regionmask

tibet = gpd.read_file(Path(__file__).resolve().parents[1] / "data/map/Tibet/Tibet.shp")
on_tp = regionmask.mask_geopandas(tibet, u).notnull()   # True on plateau grid points
u, v = u.where(~on_tp), v.where(~on_tp)                 # same for contour fields and p-values
ax.add_geometries(tibet.geometry, crs=ccrs.PlateCarree(),
                  facecolor="lightgrey", edgecolor="grey", linewidth=0.5)

ファイルがない場合は、地表ジオポテンシャルが利用できれば標高3000 mの地形輪郭線を使用します。それ以外の場合は、図に BLOCKED と記載します。

ベクターと等値線

風とフラックスのベクターは、Skyborn の curly_vector で描画します。これはデータ場を自らサンプリングするため、[::n] で間引かないでください。以下の値は初期値です。印刷サイズで流れが明瞭に読み取れるよう、RR 中に密度、矢印の長さ、線幅、キーを調整します。

from skyborn.plot import curly_vector, curly_vector_key

cv = curly_vector(ax, lon, lat, u, v, transform=ccrs.PlateCarree(),
                  density=0.5, ref_magnitude=10, ref_length=0.06,
                  color="#555555", linewidth=0.8, zorder=3)
key = curly_vector_key(ax, cv, U=10, units=r"m s$^{-1}$", labelpos="W",
                       frameon=False, show_description=False,
                       width=0, height=0, padding=0, x=1.0, y=1.02,
                       arrow_props={"color": "#555555", "linewidth": 0.8},
                       text_props={"fontsize": 8})
fig.canvas.draw()                    # after the final layout change
key.x = 1.0 - key.patch.get_width()  # key arrow tip on the map's right edge
  • ref_magnitude(解釈しやすい風速で、キーの U にもなります)を渡します。指定しない場合、各パネルはそれぞれの最大値に合わせてスケーリングされます。1つのキーを共有するパネルは、幅を同じにし、同じ ref_magnitude と ref_length を指定する必要があります。そうでない場合は、パネルごとにキーを用意します。最大風速が U 以上のパネルからキーを作成してください。Skyborn は最大風速を上限として矢印の長さを制限するためです。PlateCarree 以外の投影法では、regrid_shape によって矢印の間隔を均等にします。
  • units は mathtext で指定します。デフォルトの "m/s" は単位のルールに反します。
  • キーは地図の右上外側、文字/説明と同じ高さに1つ置き、データ場の矢印と同じスタイルにします。
  • 等値線は解釈に役立つ場合(ゼロ線、しきい値)のみ使用します。ゼロ線は濃い色で0.8~1.0 pt、その他は適度なアルファ値で0.4~0.6 ptとし、一部の等値線にのみラベルを付けます。
重要性

点は図のフィールドより目立たないようにします。デフォルトではドットを使い、パネルに合わせて間隔、サイズ、不透明度を選び、RR中に調整します。ドットが暗い塊になったり、フィールドを隠したりしてはいけません。応答の符号を区別する必要がある場合に限り、彩度を抑えた赤/青を使います。まばらな "." または ".." のハッチングを contourf(..., levels=[0, 0.05, 1], hatches=[".", None], colors="none") で描く方法もあります。

その他の図の種類
  • 時系列:細い線を使い、異常を示す場合はゼロ線または基準線を入れ、不確実性は帯状に塗りつぶして示します。
  • 断面/プロファイル:気圧軸は反転します(1000 hPaを下端に配置)。地形は灰色で塗りつぶします。
  • 相関行列:0を中心とする発散型カラーマップを使い、範囲は [-1, 1] とします。有意性はドットまたは輪郭線で示し、すべてのセルに数値を入れる方法は避けます。
  • EOF:0を中心とする発散型マップを使います。PCはゼロ線を入れて正規化し、説明分散はパネルの説明に記載して、符号の規約を明示します。
  • 散布図/回帰:r、傾き、p値は、結果の中心となる場合に限り注記します。
エクスポート

すべて600 dpiでレンダリングします。各プロットスクリプトには省略可能な --final フラグがあります。指定しない場合はRR用のPNGを、指定した場合はPNGとPDFを出力します。

exts = ("png", "pdf") if final else ("png",)
for ext in exts:
    fig.savefig(f"{stem}.{ext}", dpi=600)
plt.close(fig)

PDFのサイズが大きい場合や処理が遅い場合は、密なレイヤーに rasterized=True を渡します。

RRのルール

レビュー・改訂(RR)では、レンダリングした各図の視覚的な欠陥と明らかなデータエラーを確認します。

  • 反復ごとに、レンダリングしたPNGを開きます。コードだけをレビューしても確認したことにはなりません。
  • Plot Standardsと以下のチェックリストに照らして確認し、PASS(残件なし)、REVISE(新しい情報がなくても修正できる目に見える問題をすべて修正して、再レンダリングを一度行い、確認を繰り返す)、BLOCKED(ユーザーの判断または不足している入力が必要、あるいは出力が判読できない)に分類します。
  • PASSにする前に少なくとも1回、最大5回まで反復します。それまでにPASSにならない場合はBLOCKEDとし、残件をREADMEに記載します。
  • ベクトルの密度とキー、およびスティップリングの間隔とサイズは、ここでPNGを見ながら調整します。プロットコードでは初期値のみを設定します。
  • ルール違反がなくても、トップクラスの大気科学ジャーナルに掲載される図として不自然に見える点はすべて修正します。
チェック項目合格条件
テキストArialまたはプロジェクトのフォントを使用している。単位にはmathtextを使用している。文字が切れていない。8 pt未満の文字がない。全体タイトル、キャプション、説明文がない。
パネル太字の文字、短く中央揃えされた説明、ベクトルキーが同じベースライン上にある。
カラーマップ許可リストにあるカラーマップを使い、levelsを明示している。意味のあるゼロを持つ符号付きフィールドには0中心の発散型、その他には逐次型を使っている。extendを設定している。比較可能なパネルは同じスケールを使っている。
マップ海岸線と緯度/経度ラベルがある。日付変更線に継ぎ目がなく、空白の余白もない。
チベット700 hPa以下では高原上に矢印、等値線、ドットがない。灰色のポリゴンが描かれている。
ベクトル密度が判読可能である。キーは右上に1つだけあり、先端が右端にある。
有意性見えるが、フィールドより目立たない。
レイアウトパネルのバランスが取れている。カラーバーが細い。重なりがない。
物理値、単位、符号に妥当性がある。気圧軸が反転している。
全体トップクラスの大気科学ジャーナルにふさわしい、高品質な科学図である。

READMEテンプレート

すべての図がPASSまたはBLOCKEDになったら、中国語のREADME.mdを1つ作成します。実際のプロジェクト構成に合わせ、テンプレートに合わせるためにプロジェクトを再構成してはいけません。

# 项目说明

简要说明科学目标和主要工作内容。

## 1. 数据简述

- 输入数据路径:
- 数据来源与类型:
- 时间范围:
- 空间范围与分辨率:

## 2. 路径结构和实现功能

- `data_output/fig1/xxx.nc`:实现功能
- `fig1/compute_xxx.py`:实现功能
- `fig1/plot_xxx.py`:实现功能
- `fig1/fig1_xxx.png`、`fig1/fig1_xxx.pdf`:实现功能

## 3. 实现算法与细节

- 采用的假设与默认选择:逐条列出用户确认的选择和可逆的默认设置,算法简单时也要写。
- 算法如无需展开,可写:`本任务算法直接,省略。`
- 若有复杂处理,写清关键公式、统计方法、重网格方案和加速策略。

## 4. 可能存在的问题与风险

- 列出 `BLOCKED` 的图、原因和剩余问题,以及其他未解决的风险。
- 无则写:`目前无明显问题。`

## 5. 图片简述

- 以大气科学论文写作口径,专业、简洁地说明每张图的内容与意义。

## 6. 版本更新

- (更新时填写日期、变更内容、影响文件)

後から変更する場合は、Patch Modeも含め、「版本更新」に追記し、影響を受けるパスと図のセクションのみを更新します。

Patch Mode

既存のコードを読み、最小限かつ安全な変更を加え、影響を受ける図のみを再レンダリングし、RRを実施してエクスポートしたうえで、READMEに「版本更新」の項目を追記します。

RRで計算上のバグ(変数の誤り、単位の誤り、気候値の基準値の誤り)が見つかった場合は、パッチ作業を中断し、手順2からやり直します。

コメント