首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用NCML减少netCDF文件中的维数

使用NCML减少netCDF文件中的维数
EN

Stack Overflow用户
提问于 2013-09-17 18:24:28
回答 5查看 1.3K关注 0票数 3

我试图使用NCML将CF-1.4文件“转换”为CF-1.6。特别令人感兴趣的是如何1)删除维度,然后2)更改变量的维度。例如,下面是两个ncdump文件的顶部部分( netCDF )。第一个是CF1.4,维度为timezlatlon.在这个文件中,变量(例如,temp)是这四个:temp(time,z,lat,lon)的函数。我希望通过NCML将其转换为CF-1.6文件,如第二个文件所示,其中z/lat/lon不再是维度,变量只是时间函数。谢谢,

档案1:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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" ;
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2013-09-17 19:15:25

Update:下面的解决方案似乎是有效的,但它并不是:从它中提取数据失败了,正如John .所发现的(参见其他答案)。我们认为我们已经找到了保持单一维度的解决方案,但是从四个维度到一个维度最终会导致错误。正如Sean .指出的那样,您不能使用NcML更改变量的形状。

原始“解决方案”(实际上不起作用):

如果您的目标是使您的数据CF-1.6兼容,则可以将该维度设置为station,其值为1。所以你可以这么做:

代码语言:javascript
复制
<?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>
票数 3
EN

Stack Overflow用户

发布于 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是我们的用户委员会的成员,该委员会将于下个月举行会议。我建议他在会上也提到特写要求。

干杯!

肖恩

票数 3
EN

Stack Overflow用户

发布于 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中工作,我们必须:

  1. 添加CF-1.6‘坐标’属性("time lat lon z")
  2. 添加全局属性"featureType = timeSeries“
  3. 添加station_name变量
  4. 改变数据类型从一个点到另一个站

结果如下:

代码语言:javascript
复制
    <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>
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18857163

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档