2

以下代码从 nomad 服务器获取温度数据,并生成一个 netcdf 文件,其中包含三个维度(时间、纬度和经度)的数据。它工作正常,除非 xmin <0 和 xmax> 0。在这种情况下报告错误:

回溯(最后一次调用):文件“./make_basic.py”,第 79 行,在 tmpvar[:]=var[0,xmin:xmax,ymin:ymax] 文件“netCDF4/_netCDF4.pyx”,第 3695 行,在 netCDF4._netCDF4.Variable 中。getitem (netCDF4/_netCDF4.c:38039)
文件“netCDF4/_netCDF4.pyx”,第 4376 行,在 netCDF4._netCDF4.Variable._get (netCDF4/_netCDF4.c:47286) RuntimeError: NetCDF: DAP server error

如果 xmin <0 和 xmax <0,或两者都大于零,则它可以正常工作。有谁知道什么可能失败?例如,从负坐标到正坐标做一个欧洲的 netcdf 是很重要的,因为 0 是格林威治的子午线。

#! /usr/bin/python
import netCDF4
import numpy as np
import sys

dods='http://nomads.ncep.noaa.gov:9090/dods/gfs_0p25_1hr/gfs20170928/gfs_0p25_1hr_00z'
newfile='sdffile.nc'

xmin=-100
xmax=100
ymin=448
ymax=649

cdata=netCDF4.Dataset(dods,'r')

lon=cdata.variables['lon']
lat=cdata.variables['lat']
time=cdata.variables['time']
var=cdata.variables['tmp2m']

## Set Some Globals
newdata=netCDF4.Dataset(newfile,'w')
newdata.title="GFS"
newdata.Conventions="COARDS"
newdata.dataType='Grid'
newdata.history='Example Self Describing NetCDF File From GrADS-Aholic'

newdata.createDimension('lat', len(lat[ymin:ymax]))
newdata.createDimension('lon', len(lon[xmin:xmax]))
newdata.createDimension('time', 1)

### Create dimensional variables: ###
### For dimension variables, COARDS attributs are required for GrADS self describing

### Do latitude (f8 = float64):
latvar=newdata.createVariable('lat','f8',('lat'))
latvar.grads_dim='y'
latvar.grads_mapping='linear'
latvar.grads_size=len(lat[ymin:ymax])
latvar.units='degrees_north'
latvar.long_name='latitude'
latvar.minimum=str(lat[ymin])
latvar.maximum=str(lat[ymax])
latvar.resolution='0.25'
latvar[:]=lat[ymin:ymax]

### Do longitude (f8 = float64):
lonvar=newdata.createVariable('lon','f8',('lon'))
lonvar.grads_dim='x'
lonvar.grads_mapping='linear'
lonvar.grads_size=len(lon[xmin:xmax])
lonvar.units='degrees_east'
lonvar.long_name='longitude'
lonvar.minimum=str(lon[xmin])
lonvar.maximum=str(lon[xmax])
lonvar.resolution='0.25'
lonvar[:]=lon[xmin:xmax]

### Do Time (f8 = float64):
### Added grads_min and grads_step to attributes
timevar=newdata.createVariable('time','f8',('time'))
timevar.grads_dim='t'
timevar.grads_mapping='linear'
timevar.grads_size=1
timevar.units='days since 1-1-1 00:00:0.0'
timevar.grads_min='00z30dec2015'
timevar.grads_step='3hr'
timevar.long_name='time'
timevar.minimum='00z30dec2015'
timevar.maximum='00z31dec2015'
timevar.resolution='0.125'
timevar[:]=time[0]

### Now that dimensional variables are finished, the other variables are written
### 2 meter temperature (f4=float32) ###
tmpvar=newdata.createVariable('TMP','f4',('time','lat','lon'),fill_value=9.999E20)
tmpvar.long_name='2 Meter Temperature'
tmpvar.units='K'
tmpvar[:]=var[0,xmin:xmax,ymin:ymax]
print 'Done with 2 meter Temperature!'

newdata.close()

cdata.close()

sys.exit()
4

1 回答 1

0

创建所有实例时,您确定这可以正常工作吗?我一直在查看您的代码,但我怀疑它的行为是否符合您的预期。

#! /usr/bin/python                                                                                                                                                                            

# Python package imports
import sys

# Third party imports
import netCDF4
import numpy as np

# Package imports

# code

dods=('http://nomads.ncep.noaa.gov:9090/dods/gfs_0p25_1hr/'                     
      'gfs20180221/gfs_0p25_1hr_00z')                                           

# I changed the link because the link below is unavailable                      

# dods=('http://nomads.ncep.noaa.gov:9090/dods/gfs_0p25_1hr/'                   

#       'gfs20170928/gfs_0p25_1hr_00z')   
newfile='sdffile.nc'

xmin=-100
xmax=100
ymin=448
ymax=649

cdata=netCDF4.Dataset(dods,'r')

lon=cdata.variables['lon']
lat=cdata.variables['lat']
time=cdata.variables['time']
var=cdata.variables['tmp2m']
print(lon)
print(var)
## Set Some Globals
newdata=netCDF4.Dataset(newfile,'w')
newdata.title="GFS"
newdata.Conventions="COARDS"
newdata.dataType='Grid'
newdata.history='Example Self Describing NetCDF File From GrADS-Aholic'

print(len(lat[ymin:ymax]))
print(len(lon[xmin:xmax]))

newdata.createDimension('lat', len(lat[ymin:ymax]))  # this is a potential problem
newdata.createDimension('lon', len(lon[xmin:xmax]))  # this is a potential problem
newdata.createDimension('time', 1)

print(newdata.dimensions['lat'])
print(newdata.dimensions['lon'])
cdata.close()
sys.exit()

这会产生以下输出:

$ python stackoverflow.py 
<class 'netCDF4._netCDF4.Variable'>
float64 lon(lon)
    grads_dim: x
    grads_mapping: linear
    grads_size: 1440
    units: degrees_east
    long_name: longitude
    minimum: 0.0
    maximum: 359.75
    resolution: 0.25
unlimited dimensions: 
current shape = (1440,)
filling off

<class 'netCDF4._netCDF4.Variable'>
float32 tmp2m(time, lat, lon)
    _FillValue: 9.999e+20
    missing_value: 9.999e+20
    long_name: ** 2 m above ground temperature [k] 
unlimited dimensions: 
current shape = (121, 721, 1440)
filling off

201  # the length of your 'lat' dimension
0    # the length of your 'lon' dimension, making it unlimited
<class 'netCDF4._netCDF4.Dimension'>: name = 'lat', size = 201

<class 'netCDF4._netCDF4.Dimension'> (unlimited): name = 'lon', size = 0

在 python 中,array[start:end]通常从您想要的数组中选择范围。数组从 0 开始并以 1 递增。当您混合正数和负数来对数组进行切片时,它的工作方式与在数轴上不同。负数表示从数组末尾开始计数。正数表示从数组的开头开始计数。你开始进入阵列比你结束。这是创建一个零长度数组并告诉 netCDF 创建一个无限变量。我不认为这是你想要做的。为了在较小的范围内说明这一点,我们将使用一个大小为 5 的数组。

xmin = -2  
xmax = 2

lon = np.arange(5)  # array([0, 1, 2, 3, 4])
lon[2:-2]  # produces a result because you're increasing the array index.
           # starting at 2 and moving forward to 2 before the end of the array
           # this selects item 2 because it starts at lon[2] which is 2 and ends
           # at lon at 2 because it is 2 spaces from the end of the array
lon[-2:-1]  # this works because you're starting two away from the end and moving
            # to one index away from the end of the array.  The starting index
            # is still smaller than the ending index
lon[-2:2]   # will not work because you are telling the array to start two places
            # from the end of the array and move to the second spot in the array.
            # the array is not a queue.  It will not hit the tail and start over.
            #  It will move to the second spot from the end of the array and return
            # an empty array because it is already past the end position you specified.
            # this returns array([], dtype=int64).  calling len() on this gives 0
于 2018-02-21T17:33:32.177 回答