我试图使用NCML将CF-1.4文件“转换”为CF-1.6。特别令人感兴趣的是如何1)删除维度,然后2)更改变量的维度。例如,下面是两个ncdump文件的顶部部分( netCDF )。第一个是CF1.4,维度为time、z、lat和lon.在这个文件中,变量(例如,temp)是这四个:temp(time,z,lat,lon)的函数。我希望通过NCML将其转换为CF-1.6文件,如第二个文件所示,其中z/lat/lon不再是维度,变量只是时间函数。谢谢,
档案1:
netcdf wqb_1.4 {
dimensions:
time = UNLIMITED ; // (109008 currently)
z = 1 ;
lat = 1 ;
lon = 1 ;
variables:
float time(time) ;
time:long_name = "Time" ;
time:standard_name = "time" ;
time:short_name = "time" ;
time:axis = "T" ;
time:units = "minutes since 2008-01-01 00:00:00 -10:00" ;
float z(z) ;
z:long_name = "depth below mean sea level" ;
z:standard_name = "depth" ;
z:short_name = "depth" ;
z:axis = "z" ;
z:units = "meters" ;
float lat(lat) ;
lat:long_name = "Latitude" ;
lat:standard_name = "latitude" ;
lat:short_name = "lat" ;
lat:axis = "Y" ;
lat:units = "degrees_north" ;
float lon(lon) ;
lon:long_name = "Longitude" ;
lon:standard_name = "longitude" ;
lon:short_name = "lon" ;
lon:axis = "X" ;
lon:units = "degrees_east" ;
float temp(time, z, lat, lon) ;
temp:long_name = "Temperature" ;
temp:standard_name = "sea_water_temperature" ;
temp:short_name = "temp" ;
temp:units = "Celsius" ;
temp:coordinates = "time lat lon alt" ;
temp:valid_range = 10., 35. ;
temp:_FillValue = -999.f ;
temp:observation_type = "measured" ;档案2:
netcdf wqb_1.6 {
dimensions:
time = UNLIMITED ; // (109008 currently)
name_strlen = 5 ;
variables:
char station_name(name_strlen) ;
station_name:long_name = "wqbaw" ;
station_name:cf_role = "timeseries_id" ;
float time(time) ;
time:long_name = "Time" ;
time:standard_name = "time" ;
time:short_name = "time" ;
time:axis = "T" ;
time:units = "minutes since 2008-01-01 00:00:00 -10:00" ;
float z ;
z:long_name = "depth below mean sea level" ;
z:standard_name = "depth" ;
z:short_name = "depth" ;
z:axis = "z" ;
z:units = "meters" ;
float lat ;
lat:long_name = "Latitude" ;
lat:standard_name = "latitude" ;
lat:short_name = "lat" ;
lat:axis = "Y" ;
lat:units = "degrees_north" ;
float lon ;
lon:long_name = "Longitude" ;
lon:standard_name = "longitude" ;
lon:short_name = "lon" ;
lon:axis = "X" ;
lon:units = "degrees_east" ;
float temp(time) ;
temp:long_name = "Temperature" ;
temp:standard_name = "sea_water_temperature" ;
temp:short_name = "temp" ;
temp:units = "Celsius" ;
temp:coordinates = "time lat lon alt" ;
temp:valid_range = 10., 35. ;
temp:_FillValue = -999.f ;
temp:observation_type = "measured" ;发布于 2013-09-17 19:15:25
Update:下面的解决方案似乎是有效的,但它并不是:从它中提取数据失败了,正如John .所发现的(参见其他答案)。我们认为我们已经找到了保持单一维度的解决方案,但是从四个维度到一个维度最终会导致错误。正如Sean .指出的那样,您不能使用NcML更改变量的形状。
原始“解决方案”(实际上不起作用):
如果您的目标是使您的数据CF-1.6兼容,则可以将该维度设置为station,其值为1。所以你可以这么做:
<?xml version="1.0" encoding="UTF-8"?>
<netcdf xmlns="http://www.unidata.ucar.edu/namespaces/netcdf/ncml-2.2" location="/usgs/data/file1.nc">
<remove type="dimension" name="lon"/>
<remove type="dimension" name="lat"/>
<remove type="dimension" name="z"/>
<dimension name="station" length="1"/>
<dimension name="name_strlen" length="20" />
<variable name="lat" shape="station"/>
<variable name="lon" shape="station"/>
<variable name="z" shape="station"/>
<variable name="temp" shape="time station"/>
<variable name="site" shape="station name_strlen" type="char">
<attribute name="standard_name" value="station_id" />
<attribute name="cf_role" value="timeseries_id" />
<values> my_station_001 </values>
</variable>
<attribute name="Conventions" value="CF-1.6" />
<attribute name="featureType" value="timeSeries" />
</netcdf>发布于 2013-09-18 16:27:18
里奇的解决方案将在这个非常具体的案例中起一定作用,但其原因是错误的。在NcML中,可以删除维度对象,但不能重新构造数据变量。在这种特殊情况下,您试图移除单例维度(大小为1),因为它并没有真正改变数据在磁盘上的布局方式,因此看起来是可行的。例如,如果您使用Unidata的toolsUI为temp变量执行ncdump,使用Rich‘dimensions中的NcML,您将看到单例维度仍然存在,并且还没有真正被删除。我不知道这会如何影响您的文件的读取-我认为它将取决于客户端。然而,如果你试图移除非单子维度,那么这将失败。
如果你真的想要正确地重塑你的数据,你必须重写你的netCDF文件。不幸的是,据我所知,这方面没有任何“捷径”。例如,如果您在Unidata的NcML中使用的toolsUI并尝试基于它写出一个新文件,您将得到一个错误,例如" error :第(1)节中的范围数必须为变量z=0“。这是因为单例维度仍然存在于netCDF文件中,但是NcML文件试图将范围强制为0。但是,如果您知道python,那么编写一个脚本来重写您的netCDF文件应该是非常直接的。
请注意,使用NcML重新构造变量的能力是我们定期听到的一个特性请求-发送特性请求以支持-netcdf@unidata.ucar.edu不会有什么影响。还请注意,Unidata是一个社区驱动的组织,Rich是我们的用户委员会的成员,该委员会将于下个月举行会议。我建议他在会上也提到特写要求。
干杯!
肖恩
发布于 2013-09-25 18:24:15
里奇是对的,这样做的目的是尝试将我们的数据提升到CF-1.6,这样我们就可以通过SOS来服务我们的数据。更具体地说,我们希望使用ncSOS (构建在TDS上),而这种特殊的SOS风格需要CF-1.6。在这方面,通过NCML进行的修改似乎有效(加上一些附加的修改,请参见下文)。
我不想修改数据集,其中有些数据可以追溯到几年前。Sean关于客户端工具的观点也是相关的,因为我们的许多用例都涉及需要变量才能具有lat/lon维度的工具。因此,我们的解决方案是通过两个NCML“包装器”通过TDS提供一个数据集,一个用于ncSOS,另一个用于通过OPeNDAP访问需要lat/lon的特定客户端。
除了里奇上面的建议外,为了在ncSOS中工作,我们必须:
结果如下:
<attribute name="featureType" value="timeSeries" />
<remove type="dimension" name="lon"/>
<remove type="dimension" name="lat"/>
<remove type="dimension" name="z"/>
<dimension name="name_strlen" length="4"/>
<variable name="lat" shape=""/>
<variable name="lon" shape=""/>
<variable name="z" shape=""/>
<variable name="station_name" shape="name_strlen" type="char">
<attribute name="long_name" value="NS01" />
<attribute name="cf_role" value="timeseries_id" />
<values>NS01</values>
</variable>
<variable name="temp" shape="time">
<attribute name="coordinates" value="time lat lon z" />
</variable>https://stackoverflow.com/questions/18857163
复制相似问题