decode_vertical_coords gives wrong depths for ocean_s_coordinate and ocean_s_coordinate_g1
还没有人认领这个 Issue。
评估
调研方向
从 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.decodeuses lowercasesinstead ofS:z = S + self.eta * (1 + self.s / self.depth).OceanS.decodeis missing parentheses:np.tanh(self.a * (self.s + 0.5)) / 2 * np.tanh(0.5 * self.a)divides by 2 and then multiplies bytanh(0.5*a), instead of dividing by2 * 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,通用步骤见我们的新手贡献指南。
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
xarray-contrib/cf-xarray 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 68/100
xarray-contrib/cf-xarray#623 ·
-
Consider adding opt-in support for circular axes when calling `bounds_to_vertices` (related to #594)未关闭
难度 5/5 一周以上 新手友好度 38/100
xarray-contrib/cf-xarray#596 · 1 条评论 ·
-
难度 3/5 1-2 天 新手友好度 25/100
xarray-contrib/cf-xarray#570 ·
-
难度 4/5 3-5 天 新手友好度 15/100
xarray-contrib/cf-xarray#568 ·
-
难度 3/5 1-2 天 新手友好度 35/100
xarray-contrib/cf-xarray#566 · 2 条评论 ·
查看 xarray-contrib/cf-xarray 的全部 Issue
相似的 Issue
-
难度 1/5 1 小时以内 新手友好度 72/100
-
[Bug]: Importing weave changes the process-wide locale可能已有人在做 @himanshu748 今天认领。 未关闭bug
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 68/100
-
bug
难度 2/5 1-3 小时 新手友好度 74/100
-
UX
难度 1/5 1 小时以内 新手友好度 72/100
mediajunkie/piper-morgan-product#2008 · 2 条评论 ·