Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

decode_vertical_coords gives wrong depths for ocean_s_coordinate and ocean_s_coordinate_g1

クローズ 初心者向け
#666 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
88/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
python
領域
data

調査の方向性

cf_xarray/parametric.py の OceanSG1.decode と OceanS.decode から始め、次に issue の reproducer を実行して、両方のデコード済み配列を Appendix D の式と比較します。s = -1 で z = -depth になり、eta = 0 の s = 0 で ocean_s_coordinate が z = 0 になることも含め、2 つの実装がそれらの式と一致すれば完了です。

索引モデルが issue の本文から書いたものです。

説明

Two of the ocean formulas in cf_xarray/parametric.py don't match CF Appendix D, so the bottom level doesn't land on -depth and the surface doesn't land on eta.

import numpy as np
import xarray as xr
import cf_xarray

print(cf_xarray.__version__)

# ocean_s_coordinate_g1
s = np.array([-1.0, -0.5, 0.0])
C = np.array([-1.0, -0.3, 0.0])
eta, depth, depth_c = 2.0, 100.0, 10.0
ds = xr.Dataset(
    {
        "C": ("s_rho", C),
        "eta": ((), eta, {"standard_name": "sea_surface_height_above_geoid"}),
        "depth": ((), depth, {"standard_name": "sea_floor_depth_below_geoid"}),
        "depth_c": ((), depth_c),
    },
    coords={
        "s_rho": (
            "s_rho",
            s,
            {
                "standard_name": "ocean_s_coordinate_g1",
                "formula_terms": "s: s_rho C: C eta: eta depth: depth depth_c: depth_c",
            },
        )
    },
)
ds.cf.decode_vertical_coords(outnames={"s_rho": "z_rho"})
print(ds.z_rho.values)
S = depth_c * s + (depth - depth_c) * C
print(S + eta * (1 + S / depth))

# ocean_s_coordinate
eta, a, b = 0.0, 5.0, 1.0
ds = xr.Dataset(
    {
        "eta": ((), eta, {"standard_name": "sea_surface_height_above_geoid"}),
        "depth": ((), depth, {"standard_name": "sea_floor_depth_below_geoid"}),
        "depth_c": ((), depth_c),
        "a": ((), a),
        "b": ((), b),
    },
    coords={
        "s": (
            "s",
            s,
            {
                "standard_name": "ocean_s_coordinate",
                "formula_terms": "s: s eta: eta depth: depth a: a b: b depth_c: depth_c",
            },
        )
    },
)
ds.cf.decode_vertical_coords(outnames={"s": "z"})
print(ds.z.values)
C = (1 - b) * np.sinh(a * s) / np.sinh(a) + b * (
    np.tanh(a * (s + 0.5)) / (2 * np.tanh(0.5 * a)) - 0.5
)
print(eta * (1 + s) + depth_c * s + (depth - depth_c) * C)

Output:

0.11.3
[-98.02 -30.01   2.  ]
[-100.    -30.64    2.  ]
[-98.8033498 -50.         -1.1966502]
[-100.  -50.    0.]

Expected the first and third lines to equal the second and fourth. In both cases s = -1 should give z = -depth (-100), and for ocean_s_coordinate with eta = 0, s = 0 should give z = 0.

Formulas from Appendix D (https://cfconventions.org/cf-conventions/cf-conventions.html#parametric-v-coord):

ocean_s_coordinate_g1:
  z = S + eta * (1 + S / depth)
  S = depth_c * s + (depth - depth_c) * C

ocean_s_coordinate:
  C = (1-b)*sinh(a*s)/sinh(a) + b*[tanh(a*(s+0.5))/(2*tanh(0.5*a)) - 0.5]

Causes in cf_xarray/parametric.py:

  • OceanSG1.decode uses lowercase s instead of S: z = S + self.eta * (1 + self.s / self.depth).
  • OceanS.decode is missing parentheses: np.tanh(self.a * (self.s + 0.5)) / 2 * np.tanh(0.5 * self.a) divides by 2 and then multiplies by tanh(0.5*a), instead of dividing by 2 * tanh(0.5*a).

Same output on cf_xarray 0.11.3 from PyPI and on main at 27e104c9ff4297b75412f71b5cee0fd1473a46f9. xarray 2026.9.0, numpy 2.2.6 (also 2.5.3 on the main install), Python 3.12, macOS.

主要言語
Python
スター
181
フォーク
51
平均マージ
6時間 39分
マージ済み PR(30日)
1

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

xarray-contrib/cf-xarray のほかの issue

xarray-contrib/cf-xarray の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。