2336 字
12 分钟
OceanSpy:一个提供海洋数值模式数据分析和可视化的Python包

****

随着数值海洋环流模式的时间和空间分辨率不断提高以及物理过程刻画更加完善,模式计算输出的数据量呈现爆炸性增长,这给海洋科学研究人员在数据分析和知识提取方面带来了巨大挑战。

这些挑战主要体现在两个方面:首先,庞大的数据规模需要高性能计算基础设施来支持数据访问和处理;其次,原始模型输出通常需要复杂的后处理才能提取出有意义的海洋学信息。此外,为了验证数值模式的真实性和准确性,需要将模式计算结果与实际观测数据进行对比,这就要求分析技术必须与海洋观测学家使用的方法保持一致。

针对这些挑战,OceanSpy应运而生。这个开源的Python包集成了Xarray、Dask和Xgcm等强大的数据处理库,为海洋数值模式数据的分析和可视化提供了一个用户友好的解决方案。它不仅支持可扩展的数据分析和高效的海洋特性提取,还提供了强大的诊断计算能力和灵活的可视化功能。

1. OceanSpy主要特性#

OceanSpy被设计为一个易于使用且多功能的Python包,其核心功能可分为以下几类:

海洋特性数据提取#

  • 用户自定义点位:在4D空间(经度、纬度、深度、时间)的特定位置提取模型场数据(温度、盐度、速度等)。这对于将模型输出与点测量或拉格朗日仪器进行比较至关重要。
  • 合成船舶调查:通过提取连接用户定义”站点”的大圆路径上的垂直剖面来模拟水文调查。数据被插值到这些站点上,允许进行类似于观测调查的垂直剖面分析。
  • 合成锚系阵列:在固定位置提取数据,保持数据在原始模式网格上,便于精确计算物质通量。

这些提取功能使研究人员能够直接将模式模拟结果与各种类型的观测数据进行比较,包括拉格朗日漂流和水文调查。

诊断量计算#

除了简单提取原始模型变量外,OceanSpy还可以计算许多模式未直接输出的衍生海洋学诊断量。这些包括:

  • 矢量微积分运算:标量和矢量场的梯度、散度、旋度和拉普拉斯算子。
  • 海洋物理变量:Ertel potential vorticity, Brunt-Väisälä frequency, potential density anomaly, relative vorticity, kinetic energy (total and eddy), and various strain components (horizontal shear and normal strain).
  • 体积加权平均:计算特定体积的平均值。
  • 收支分析:在具备必要模型输出的情况下,可进行热量和盐分收支的精确计算

下表总结了OceanSpy可计算的部分诊断量,并提供了每个诊断量的数学定义。

简便的可视化#

OceanSpy与matplotlib和Xarray的绘图功能无缝集成,提供针对海洋数据可视化的定制函数。常见的可视化,如:温度-盐度(T/S)图、海表温度分布图、水文断面图等。

模式兼容性和可扩展性#

虽然OceanSpy主要是与MITgcm的输出一起开发和测试的,但它可以兼容任何结构化网格海洋通用环流模式。其架构具有灵活性,允许实现数值模式特定的特性,如不同的网格、数值方案、收支闭合和状态方程。

OceanSpy利用Dask实现了可扩展性,这对于处理现代高分辨率模拟产生的PB级数据集至关重要。它可以部署在各种环境中:

  • 独立包:用于本地分析模型输出。
  • 远程数据分析集群:基于云计算集群平台环境,直接在远程数据分析环境分析可视化大型数据集。

2. 安装#

OceanSpy可以使用conda轻松安装。推荐的安装过程涉及使用conda-forge通道创建专用conda环境,确保安装所有必要的依赖项。以下命令创建一个名为”oceanspy-env”的环境,其中包含OceanSpy及其依赖项:

conda create -n oceanspy-env -c conda-forge oceanspy xarray dask xgcm “cartopy<0.20” esmpy intake-xarray geopy xesmf esmf xgcm Ipython tqdm ffmpeg aiohttp pandas xmitgcm

3. 应用案例#

Kögur断面:分析水文断面#

Kögur断面是冰岛和格陵兰之间经常采样的水文断面,是OceanSpy应用的绝佳例子。使用OceanSpy,可以轻松:

  • 采样模型输出:沿Kögur断面提取数据,模仿观测调查和锚系部署。
  • 计算正交速度:计算并可视化垂直于断面的速度分量,揭示横断面流型。
  • 分析体积输运:计算通过断面的密水体积通量时间序列,量化重要的水团输运。
  • 探索T/S特性:生成按正交速度着色的T/S图,揭示水团特征与流向之间的关系。

这些功能允许将模型模拟与Kögur断面的观测数据直接比较,有助于模式验证和过程理解。

1# Import oceanspy
2import cartopy.crs as ccrs
3import matplotlib.pyplot as plt
4import oceanspy as ospy
5
6od = ospy.open_oceandataset.from_catalog(“EGshelfIIseas2km_ASR_full”)
7
8# Kögur information
9lats_Kogur = [68.68, 67.52, 66.49]
10lons_Kogur = [-26.28, -23.77, -22.99]
11depth_Kogur = [0, -1750]
12
13# Select time range:
14# September 2007, extracting one snapshot every 3 days
15timeRange = [“2007-09-01”, “2007-09-30T18”]
16timeFreq = “3D”
17
18# Extract mooring array and fields
19od_moor = od.subsample.mooring_array(
20 Xmoor=lons_Kogur,
21 Ymoor=lats_Kogur,
22 ZRange=depth_Kogur,
23 timeRange=timeRange,
24 timeFreq=timeFreq,
25 varList=[“Temp”, “S”, “U”, “V”, “dyG”, “dxG”, “drF”, “HFacS”, “HFacW”],
26)
27
28# Store the new mooring dataset
29filename = “Kogur_mooring.nc”
30od_moor.to_netcdf(filename)
31
32# The NetCDF can now be re-opened with oceanspy at any time,
33# and on any computer
34od_moor = ospy.open_oceandataset.from_netcdf(filename)
35
36# Plot map and mooring locations
37fig = plt.figure(figsize=(5, 5))
38ax = od.plot.horizontal_section(varName=“Depth”)
39XC = od_moor.dataset[“XC”].squeeze()
40YC = od_moor.dataset[“YC”].squeeze()
41line = ax.plot(XC, YC, “r.”, transform=ccrs.PlateCarree())
42

1# Plot time mean
2ax = od_moor.plot.vertical_section(
3 varName=“V”,
4 contourName=“Sigma0”,
5 meanAxes=“time”,
6 robust=True,
7 cmap=“coolwarm”,
8)

1# Plot all snapshots
2ax = od_moor.plot.vertical_section(
3 varName=“V”, contourName=“Sigma0”, robust=True, cmap=“coolwarm”, col_wrap=5
4)
5# Alternatively, use the following command to produce a movie:
6# anim = od_moor.animate.vertical_section(varName=‘V’, contourName=‘Sigma0’, …)

1ax = od_moor.plot.TS_diagram(
2 colorName=“V”,
3 meanAxes=“time”,
4 cmap_kwargs={“robust”: True, “cmap”: “coolwarm”},
5)

拉格朗日粒子轨迹#

在粒子跟踪用例中,OceanSpy可以沿预先计算的拉格朗日粒子轨迹对模型数据进行子采样。虽然OceanSpy本身目前不计算轨迹,但它可以沿现有粒子路径高效提取模型特性(如温度)。这使得能够分析模拟海洋中的粒子行为,模仿RAFOS浮标等拉格朗日仪器收集的数据。

1ods = [od_dense, od_mixed]
2colors = [“fuchsia”, “lime”]
3titles = [
4 r”Particles always denser than 27.8 kg m3^{-3}.”,
5 r”Particles ONLY initially denser than 27.8 kg m3^{-3}”,
6]
7for _, (od_i, col, tit) in enumerate(zip(ods, colors, titles)):
8 # Plot Depth
9 fig = plt.figure(figsize=(10, 5))
10 ax = od_eul.plot.horizontal_section(varName=“masked_Depth”, cmap=“bone_r”)
11 land_col = (253 / 255, 180 / 255, 108 / 255)
12 ax.patch.set_facecolor(land_col)
13 ax.set_extent([-40, -19, 63, 68])
14
15 # Plot trajectories
16 ax.plot(
17 od_i.dataset[“XC”],
18 od_i.dataset[“YC”],
19 color=col,
20 alpha=0.2,
21 linewidth=1,
22 transform=PlateCarree(),
23 )
24
25 # Plot initial positions
26 ax.plot(
27 od_i.dataset[“XC”].isel(time=0),
28 od_i.dataset[“YC”].isel(time=0),
29 “k.”,
30 markersize=5,
31 transform=PlateCarree(),
32 )
33
34 # Title
35 _ = ax.set_title(tit)
36 plt.show()

以下动画通过在丹麦海峡释放并随时间跟踪的粒子演示了这一功能,展示了沿其3D轨迹的温度演变。

References:#

本公众号相关内容推荐#

OceanSpy:一个提供海洋数值模式数据分析和可视化的Python包
https://blog.scidatalab.net/posts/oceanspy-一个提供海洋数值模式数据分析和可视化的python包/
作者
Echo
发布于
2025-02-01
许可协议
CC BY-NC-SA 4.0