A variable’s spatiotemporal dimensions are used to locate data values in time and space. This is accomplished by associating these dimensions with the relevant set of latitude, longitude, vertical, and time coordinates. This section presents two methods for making that association: the use of coordinate variables, and the use of auxiliary coordinate variables.
All of a variable’s dimensions that are latitude, longitude, vertical, or time dimensions (see [terminology]) must have corresponding coordinate variables, i.e., one-dimensional variables with the same name as the dimension (see examples in [coordinate-types]). This is the only method of associating dimensions with coordinates that is supported by [COARDS].
All of a variable’s spatiotemporal dimensions that are not latitude,
longitude, vertical, or time dimensions are required to be associated
with the relevant latitude, longitude, vertical, or time coordinates via
the new coordinates
attribute of the variable. The value of the
coordinates
attribute is a blank separated list of the names of
auxiliary coordinate variables. There is no restriction on the order
in which the auxiliary coordinate variables appear in the
coordinates
attribute string. The dimensions of an auxiliary
coordinate variable must be a subset of the dimensions of the variable
with which the coordinate is associated, with two exceptions. First,
string-valued coordinates ([labels]) have a dimension for maximum
string length. Second, in the ragged array representations of data
([discrete-sampling-geometries]), special methods are needed to
connect the data and coordinates
We recommend that the name of a multidimensional coordinate variable should not match the name of any of its dimensions because that precludes supplying a coordinate variable for the dimension. This practice also avoids potential bugs in applications that determine coordinate variables by only checking for a name match between a dimension and a variable and not checking that the variable is one dimensional.
The use of coordinate variables is required whenever they are applicable. That is, auxiliary coordinate variables may not be used as the only way to identify latitude and longitude coordinates that could be identified using coordinate variables. This is both to enhance conformance to COARDS and to facilitate the use of generic applications that recognize the NUG convention for coordinate variables. An application that is trying to find the latitude coordinate of a variable should always look first to see if any of the variable’s dimensions correspond to a latitude coordinate variable. If the latitude coordinate is not found this way, then the auxiliary coordinate variables listed by the coordinates
attribute should be checked. Note that it is permissible, but optional, to list coordinate variables as well as auxiliary coordinate variables in the coordinates
attribute.
If an axis
attribute is attached to an auxiliary coordinate variable, it can be used by applications in the same way the axis
attribute attached to a coordinate variable is used. However, it is not permissible for a data variable to have both a coordinate variable and an auxiliary coordinate variable, or more than one of either type of variable, having an axis
attribute with any given value e.g. there must be no more than one axis
attribute for X
for any data variable. Note that if the axis
attribute is not specified for an auxiliary coordinate variable, it may still be possible to determine if it is a spatiotemporal dimension from its own units or standard_name, or from the units and standard_name of the coordinate variable corresponding to its dimensions (see [coordinate-types]). For instance, auxiliary coordinate variables which lie on the horizontal surface can be identified as such by their dimensions being horizontal. Horizontal dimensions are those whose coordinate variables have an axis
attribute of X
or Y
, or a units
attribute indicating latitude and longitude.
If the coordinate variables for a horizontal grid are not longitude and latitude, it is recommended that they be supplied in addition to the required coordinates. For example, the Cartesian coordinates of a map projection should be supplied as coordinate variables in addition to the required two-dimensional latitude and longitude variables that are identified via the coordinates
attribute. The use of the axis
attribute with values X
and Y
is recommended for the coordinate variables (see [coordinate-types]).
It is sometimes not practical to specify the latitude-longitude location of data which is representative of geographic regions with complex boundaries. For this purpose, provision is made in [geographic-regions] for indicating the region by a standardized name.
When each of a variable’s spatiotemporal dimensions is a latitude, longitude, vertical, or time dimension, then each axis is identified by a coordinate variable.
dimensions: lat = 18 ; lon = 36 ; pres = 15 ; time = 4 ; variables: float xwind(time,pres,lat,lon) ; xwind:long_name = "zonal wind" ; xwind:units = "m/s" ; float lon(lon) ; lon:long_name = "longitude" ; lon:units = "degrees_east" ; float lat(lat) ; lat:long_name = "latitude" ; lat:units = "degrees_north" ; float pres(pres) ; pres:long_name = "pressure" ; pres:units = "hPa" ; double time(time) ; time:long_name = "time" ; time:units = "days since 1990-1-1 0:0:0" ;
xwind(n,k,j,i)
is associated with the coordinate values lon(i)
, lat(j)
, pres(k)
, and time(n)
.
The latitude and longitude coordinates of a horizontal grid that was not defined as a Cartesian product of latitude and longitude axes, can sometimes be represented using two-dimensional coordinate variables. These variables are identified as coordinates by use of the coordinates
attribute.
dimensions: xc = 128 ; yc = 64 ; lev = 18 ; variables: float T(lev,yc,xc) ; T:long_name = "temperature" ; T:units = "K" ; T:coordinates = "lon lat" ; float xc(xc) ; xc:axis = "X" ; xc:long_name = "x-coordinate in Cartesian system" ; xc:units = "m" ; float yc(yc) ; yc:axis = "Y" ; yc:long_name = "y-coordinate in Cartesian system" ; yc:units = "m" ; float lev(lev) ; lev:long_name = "pressure level" ; lev:units = "hPa" ; float lon(yc,xc) ; lon:long_name = "longitude" ; lon:units = "degrees_east" ; float lat(yc,xc) ; lat:long_name = "latitude" ; lat:units = "degrees_north" ;
T(k,j,i)
is associated with the coordinate values lon(j,i)
, lat(j,i)
, and lev(k)
. The vertical coordinate is represented by the coordinate variable lev(lev)
and the latitude and longitude coordinates are represented by the auxiliary coordinate variables lat(yc,xc)
and lon(yc,xc)
which are identified by the coordinates
attribute.
Note that coordinate variables are also defined for the xc
and yc
dimensions. This faciliates processing of this data by generic applications that don’t recognize the multidimensional latitude and longitude coordinates.
A "reduced" longitude-latitude grid is one in which the points are arranged along constant latitude lines with the number of points on a latitude line decreasing toward the poles. Storing this type of gridded data in two-dimensional arrays wastes space, and results in the presence of missing values in the 2D coordinate variables. We recommend that this type of gridded data be stored using the compression scheme described in [compression-by-gathering]. Compression by gathering preserves structure by storing a set of indices that allows an application to easily scatter the compressed data back to two-dimensional arrays. The compressed latitude and longitude auxiliary coordinate variables are identified by the coordinates
attribute.
dimensions: londim = 128 ; latdim = 64 ; rgrid = 6144 ; variables: float PS(rgrid) ; PS:long_name = "surface pressure" ; PS:units = "Pa" ; PS:coordinates = "lon lat" ; float lon(rgrid) ; lon:long_name = "longitude" ; lon:units = "degrees_east" ; float lat(rgrid) ; lat:long_name = "latitude" ; lat:units = "degrees_north" ; int rgrid(rgrid); rgrid:compress = "latdim londim";
PS(n)
is associated with the coordinate values lon(n)
, lat(n)
. Compressed grid index (n)
would be assigned to 2D index (j,i)
(C index conventions) where
j = rgrid(n) / 128 i = rgrid(n) - 128*j
Notice that even if an application does not recognize the compress
attribute, the grids stored in this format can still be handled, by an application that recognizes the coordinates
attribute.
This section has been superseded by the treatment of time series as a type of discrete sampling geometry in Chapter 9.
This section has been superseded by the treatment of time series as a type of discrete sampling geometry in Chapter 9.
When the coordinate variables for a horizontal grid are not longitude and latitude, it is required that the true latitude and longitude coordinates be supplied via the coordinates
attribute. If in addition it is desired to describe the mapping between the given coordinate variables and the true latitude and longitude coordinates, the attribute grid_mapping
may be used to supply this description. This attribute is attached to data variables so that variables with different mappings may be present in a single file. The attribute takes a string value which is the name of another variable in the file that provides the description of the mapping via a collection of attached attributes. This variable is called a grid mapping variable and is of arbitrary type since it contains no data. Its purpose is to act as a container for the attributes that define the mapping. The one attribute that all grid mapping variables must have is grid_mapping_name
which takes a string value that contains the mapping’s name. The other attributes that define a specific mapping depend on the value of grid_mapping_name
. The valid values of grid_mapping_name
along with the attributes that provide specific map parameter values are described in [appendix-grid-mappings].
When the coordinate variables for a horizontal grid are longitude and
latitude, a grid mapping variable with grid_mapping_name
of
latitude_longitude
may be used to specify the ellipsoid and prime
meridian.
In order to make use of a grid mapping to directly calculate latitude and longitude values it is necessary to associate the coordinate variables with the independent variables of the mapping. This is done by assigning a standard_name
to the coordinate variable. The appropriate values of the standard_name
depend on the grid mapping and are given in [appendix-grid-mappings].
dimensions: rlon = 128 ; rlat = 64 ; lev = 18 ; variables: float T(lev,rlat,rlon) ; T:long_name = "temperature" ; T:units = "K" ; T:coordinates = "lon lat" ; T:grid_mapping = "rotated_pole" ; char rotated_pole rotated_pole:grid_mapping_name = "rotated_latitude_longitude" ; rotated_pole:grid_north_pole_latitude = 32.5 ; rotated_pole:grid_north_pole_longitude = 170. ; float rlon(rlon) ; rlon:long_name = "longitude in rotated pole grid" ; rlon:units = "degrees" ; rlon:standard_name = "grid_longitude"; float rlat(rlat) ; rlat:long_name = "latitude in rotated pole grid" ; rlat:units = "degrees" ; rlon:standard_name = "grid_latitude"; float lev(lev) ; lev:long_name = "pressure level" ; lev:units = "hPa" ; float lon(rlat,rlon) ; lon:long_name = "longitude" ; lon:units = "degrees_east" ; float lat(rlat,rlon) ; lat:long_name = "latitude" ; lat:units = "degrees_north" ;
A CF compliant application can determine that rlon and rlat are longitude and latitude values in the rotated grid by recognizing the standard names grid_longitude
and grid_latitude
. Note that the units of the rotated longitude and latitude axes are given as degrees
. This should prevent a COARDS compliant application from mistaking the variables rlon
and rlat
to be actual longitude and latitude coordinates. The entries for these names in the standard name table indicate the appropriate sign conventions for the units of degrees
.
dimensions: y = 228; x = 306; time = 41; variables: int Lambert_Conformal; Lambert_Conformal:grid_mapping_name = "lambert_conformal_conic"; Lambert_Conformal:standard_parallel = 25.0; Lambert_Conformal:longitude_of_central_meridian = 265.0; Lambert_Conformal:latitude_of_projection_origin = 25.0; double y(y); y:units = "km"; y:long_name = "y coordinate of projection"; y:standard_name = "projection_y_coordinate"; double x(x); x:units = "km"; x:long_name = "x coordinate of projection"; x:standard_name = "projection_x_coordinate"; double lat(y, x); lat:units = "degrees_north"; lat:long_name = "latitude coordinate"; lat:standard_name = "latitude"; double lon(y, x); lon:units = "degrees_east"; lon:long_name = "longitude coordinate"; lon:standard_name = "longitude"; int time(time); time:long_name = "forecast time"; time:units = "hours since 2004-06-23T22:00:00Z"; float Temperature(time, y, x); Temperature:units = "K"; Temperature:long_name = "Temperature @ surface"; Temperature:missing_value = 9999.0; Temperature:coordinates = "lat lon"; Temperature:grid_mapping = "Lambert_Conformal";
An application can determine that x
and y
are the projection coordinates by recognizing the standard names projection_x_coordinate
and projection_y_coordinate
. The grid mapping variable Lambert_Conformal
contains the mapping parameters as attributes, and is associated with the Temperature
variable via its grid_mapping
attribute.
dimensions: lat = 18 ; lon = 36 ; variables: double lat(lat) ; double lon(lon) ; float temp(lat, lon) ; temp:long_name = "temperature" ; temp:units = "K" ; temp:grid_mapping = "crs" ; int crs ; crs:grid_mapping_name = "latitude_longitude" crs:semi_major_axis = 6371000.0 ; crs:inverse_flattening = 0 ;
dimensions: lat = 18 ; lon = 36 ; variables: double lat(lat) ; double lon(lon) ; float temp(lat, lon) ; temp:long_name = "temperature" ; temp:units = "K" ; temp:grid_mapping = "crs" ; int crs ; crs:grid_mapping_name = "latitude_longitude"; crs:longitude_of_prime_meridian = 0.0 ; crs:semi_major_axis = 6378137.0 ; crs:inverse_flattening = 298.257223563 ;
dimensions: lat = 648 ; lon = 648 ; y = 18 ; x = 36 ; variables: double x(x) ; x:standard_name = "projection_x_coordinate" ; x:units = "m" ; double y(y) ; y:standard_name = "projection_y_coordinate" ; y:units = "m" ; double lat(y, x) ; double lon(y, x) ; float temp(y, x) ; temp:long_name = "temperature" ; temp:units = "K" ; temp:coordinates = "lat lon" ; temp:grid_mapping = "crs" ; int crs ; crs:grid_mapping_name = "transverse_mercator"; crs:semi_major_axis = 6377563.396 ; crs:semi_minor_axis = 6356256.910 ; crs:inverse_flattening = 299.3249646 ; crs:latitude_of_projection_origin = 49.0 ; crs:longitude_of_projection_origin = -2.0 ; crs:false_easting = 400000.0 ; crs:false_northing = -100000.0 ; crs:scale_factor_at_projection_origin = 0.9996012717 ;
When a variable has an associated coordinate which is single-valued, that coordinate may be represented as a scalar variable. Since there is no associated dimension these scalar coordinate variables should be attached to a data variable via the coordinates
attribute.
Under COARDS the method of providing a single valued coordinate was to add a dimension of size one to the variable, and supply the corresponding coordinate variable. The new scalar coordinate variable is a convenience feature which avoids adding size one dimensions to variables. Scalar coordinate variables have the same information content and can be used in the same contexts as a size one coordinate variable. Note however that use of this feature with a latitude, longitude, vertical, or time coordinate will inhibit COARDS conforming applications from recognizing them.
Once a name is used for a scalar coordinate variable it can not be used for a 1D coordinate variable. For this reason we strongly recommend against using a name for a scalar coordinate variable that matches the name of any dimension in the file.
dimensions: lat = 180 ; lon = 360 ; time = UNLIMITED ; variables: double atime atime:standard_name = "forecast_reference_time" ; atime:units = "hours since 1999-01-01 00:00" ; double time(time); time:standard_name = "time" ; time:units = "hours since 1999-01-01 00:00" ; double lon(lon) ; lon:long_name = "station longitude"; lon:units = "degrees_east"; double lat(lat) ; lat:long_name = "station latitude" ; lat:units = "degrees_north" ; double p500 p500:long_name = "pressure" ; p500:units = "hPa" ; p500:positive = "down" ; float height(time,lat,lon); height:long_name = "geopotential height" ; height:standard_name = "geopotential_height" ; height:units = "m" ; height:coordinates = "atime p500" ; data: time = 6., 12., 18., 24. ; atime = 0. ; p500 = 500. ;
In this example both the analysis time and the single pressure level are represented using scalar coordinate variables. The analysis time is identified by the standard name "forecast_reference_time" while the valid time of the forecast is identified by the standard name "time".