[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: NetCDF advice requested



Tommy,

> I've seen several instances of NetCDF files where global attributes
> are used when I would think scalar variables probably should be used
> instead.  For example, from an AWIPS image file:

> // global attributes:
>                 :projName = "STEREOGRAPHIC" ;
>                 :projIndex = 1. ;
>                 :centralLat = 600000. ;
>                 :centralLon = -890000. ;
>                 :lat00 = 49.3805351257324 ;
>                 :lon00 = -105.892349243164 ;
>                 :latNxNy = 34.4976844787598 ;
>                 :lonNxNy = -77.243278503418 ;
>                 :latDxDy = 43.0343055725098 ;
>                 :lonDxDy = -89.044319152832 ;
>                 :dxKm = 0.900382161140442 ;
>                 :dyKm = 0.900523722171783 ;
>                 :history = "NetCDF encoded on 13 Oct 1998 20:09:44 GMT" ;
>                 :version = "0.1" ;

> Here, I can see why history should be a global attribute, but what
> about some of the others?  What's the motivation for choosing one way
> over the other?

I don't know what the motivation was (simplicity?), and in cases like
this, I think using variables is superior to global attributes.  The
main problems with using attributes for this kind of information are:

 - you can't associate units with the attributes, because attributes
   can't have attributes;
 - you can't have information with a shape other than a vector, because
   attributes can't have a shape; and
 - you can't easily represent multiple sets of georeferencing for use by
   different variables in the same netCDF file.

We have advocated and use a different structure for this kind of
information, with a collection of variables grouped by the sharing of a
dimension, and with other variables naming the grouping dimension as a
way of pointing to their grid georeferencing, for example:

dimensions:
        ...
        nav = 1 ;               // For navigation.  Variables that use
                                // this dimension define a mapping between
                                // (x,y) indices and (lat, lon) coords.

variables:
        ...
        // navigation variables all use nav dimension

        char    nav_model(nav, nav_len) ;        // navigation parameterization
                nav_model:long_name = "navigation model name" ;

        long    grid_type_code(nav) ;
                grid_type_code:long_name = "GRIB-1 GDS data representation 
type" ;

        char    grid_type(nav, nav_len) ;
                grid_type:long_name = "GRIB-1 grid type" ;

        char    grid_name(nav, nav_len) ;
                grid_name:long_name = "grid name" ;

        long    grid_center(nav) ;
                grid_center:long_name = "GRIB-1 originating center ID" ;

        long    grid_number(nav) ;
                grid_number:long_name = "GRIB-1 catalogued grid number" ;

        char    earth_shape(nav, nav_len) ;
                earth_shape:long_name = "assumed earth shape" ;

        char    x_dim(nav, nav_len) ;
                x_dim:long_name = "x dimension name" ;

        char    y_dim(nav, nav_len) ;
                y_dim:long_name = "y dimension name" ;

        long    Nx(nav) ;
                Nx:long_name = "number of points along x-axis" ;

        long    Ny(nav) ;
                Ny:long_name =  "number of points along y-axis" ;

        float   La1(nav) ;
                La1:long_name = "latitude of first grid point" ;
                La1:units = "degrees_north" ;

        float   Lo1(nav) ;
                Lo1:long_name = "longitude of first grid point" ;
                Lo1:units = "degrees_east" ;

        byte    ResCompFlag(nav) ;
                ResCompFlag:long_name = "resolution and component flags" ;

        float   Lov(nav) ;
                Lov:long_name = "orientation of the grid" ;
                Lov:units = "degrees_east" ;

        float   Dx(nav) ;
                Dx:long_name = "x-direction grid length" ;
                Dx:units = "km" ;

        float   Dy(nav) ;
                Dy:long_name = "y-direction grid length" ;
                Dy:units = "km" ;

        byte    ProjFlag(nav) ;
                ProjFlag:long_name = "projection center flag" ;

        float   Latin1(nav) ;
                Latin1:long_name = "first intersecting latitude" ;
                Latin1:units = "degrees_north" ;

        float   Latin2(nav) ;
                Latin2:long_name = "second intersecting latitude" ;
                Latin2:units = "degrees_north" ;

        float   SpLat(nav) ;
                SpLat:long_name = "Latitude of the southern pole" ;
                SpLat:units = "degrees_north" ;

        float   SpLon(nav) ;
                SpLon:long_name = "Longitude of the southern pole" ;
                SpLon:units = "degrees_east" ;

        // end of navigation variables

        float   Z(record, level, y, x) ;
                Z:long_name = "geopotential height" ;
                Z:units = "gp m" ;
                Z:_FillValue = -9999.f ;
                Z:navigation = "nav" ;
         ...

--Russ