netcdfncmlthredds

Using NCML to reduce dimensions in netCDF file


I'm trying to use NCML to 'convert' a CF-1.4 file to CF-1.6. Of particular interest is how to 1) remove dimensions and then 2) change the dimensions of variables. For example, below are the top portions (ncdump) of two netCDF files. The first is CF-1.4, with dimensions time, z, lat and lon. In this file, variables (e.g., temp) are functions of these four: temp(time,z,lat,lon). I would like, via NCML, to convert this to a CF-1.6 file as shown in the second file, where z/lat/lon are no longer dimensions and variables are functions of time only. Thanks,

File 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" ;

File 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" ;

Solution

  • Update: The solution below appears to work, but it doesn't: extracting data from it fails, as John M. found out (see other answers). We thought we had figured out that maintaining a singleton dimension was the solution, but going from four dimensions to one dimension ultimately leads to errors. As Sean A. pointed out, you cannot change the shape of variables using NcML.

    original "solution" (doesn't actually work):

    If your goal was to make your data CF-1.6 compliant, you could make that dimension be station with a value of one. So you could do this:

    <?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>