简单,可编写脚本的方式来对非结构化THREDDS数据进行子采样?

Ste*_*ins 5 python matlab thredds opendap

我正在尝试从THREDDS提供的三角形网格模型中获取数据的子集.我希望能够指定一个LAT/LON边界框,并从该框中获取数据.数据网址是:

http://www.smast.umassd.edu:8080/thredds/dodsC/FVCOM/NECOFS/Forecasts/NECOFS_MET_FORECAST.nc

使用网格化数据,可以很容易地从THREDDS服务器对数据进行子集化.有谁知道最好的方法是获得由THREDDS服务的三角形网格的子域?

对于网格数据,我使用Ferret作为我的OPeNDAP客户端,我可以编写下载过程的脚本.虽然我可以使用Matlab,Python或其他工具,但我想在这里做类似的事情.

谢谢,

史蒂夫

Ric*_*ell 5

Opendap 和 NetCDF 不允许使用不规则索引进行提取。您只能请求开始、停止和跨步。

并且因为这是一个三角形网格,不能保证同一区域中三角形的节点具有相似的索引。因此,如果您只想获取边界框中的那些节点,则必须一一请求它们。这是缓慢的。因此,在许多情况下,确定最小和最大索引并请求整个块的速度更快,然后根据需要提取索引。

这是python中两种方法的示例比较。在这个例子中,提取包含所有索引的子集比循环每个索引快 10 倍,提取时间序列:

import netCDF4
import time
import numpy as np

url='http://www.smast.umassd.edu:8080/thredds/dodsC/FVCOM/NECOFS/Forecasts/NECOFS_GOM3_FORECAST.nc'
nc = netCDF4.Dataset(url)
ncv = nc.variables
lon = ncv['lon'][:]
lat = ncv['lat'][:]
tim = ncv['time'][:]

# find indices inside box
box = [-71.4,41,-70.2,41.5]
ii = (lon>=box[0])&(lon<=box[2])&(lat>=box[1])&(lat<=box[3])
# jj will have just indices from inside the box:
jj = np.where(ii)[0]
Run Code Online (Sandbox Code Playgroud)

如果我们遍历每个索引,它会很慢:

# loop over indices, extracting time series
time0=time.time()
zi = np.zeros((len(tim),len(jj)))
k=0
for j in jj:
    zi[:,k]=ncv['zeta'][:,j]
    k +=1
print('elapsed time: %d seconds' % (time.time()-time0))

elapsed time: 56 seconds
Run Code Online (Sandbox Code Playgroud)

但是如果我们在每个时间步都遍历范围,它会快得多:

time0=time.time()
zi2 = np.zeros((len(tim),len(jj)))
jmin=jj.min()
jmax=jj.max()

for i in range(len(tim)):
    ztmp = ncv['zeta'][i,jmin:jmax+1]
    zi2[i,:] = ztmp[jj-jmin]
print('elapsed time: %d seconds' % (time.time()-time0))

elapsed time: 6 seconds
Run Code Online (Sandbox Code Playgroud)

当然,您的结果可能会因非结构化网格的大小、子集中点的接近程度、您提取的点数等而异。但希望这能让您了解所涉及的问题。