Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

decode_vertical_coords gives wrong depths for ocean_s_coordinate and ocean_s_coordinate_g1

已关闭 适合新手
#666 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
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。

由索引模型根据 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
星标
183
派生
51
平均合并
6 小时 39 分钟
30 天内合并 PR
1

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

xarray-contrib/cf-xarray 的其他 Issue

查看 xarray-contrib/cf-xarray 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。