Aggregation may be thought of as the combination of one field into another to create a new field that occupies a larger domain. In practice, this means combining two fields so that their data arrays are concatenated along exactly one axis, as are their coordinate arrays which span that axis, in such a way that the aggregated field conforms to the CF data model.
These rules are based solely on the fields' metadata and more than two fields may ultimately be aggregated along one or more axes by repeated aggregations between pairs of fields.
time
axis. Note that the matching coordinates for
the aggregating axis comprise a CF-netCDF coordinate and a CF-netCDF
scalar coordinate.
Field 1:
dimensions: t = 12 ; // size 12 time dimension lat = 111 ; lon = 106 ; bounds = 2 ; variables: double t(t) ; // time dimension coordinate t:standard_name = "time" ; t:units = "hours since 2012-1-1" ; t:calendar = "standard" ; t:bounds = "time_bnds" ; double t_bnds(bounds) ; double lat(lat) ; lat:standard_name = "grid_latitude" ; lat:units = "degrees" ; double lon(lon) ; lon:standard_name = "grid_longitude" ; lon:units = "degrees" ; double latitude(grid_latitude, grid_longitude) ; latitude:standard_name = "latitude" ; latitude:units = "degrees_north" ; double longitude(grid_latitude, grid_longitude) ; longitude:standard_name = "longitude" ; longitude:units = "degrees_east" ; char rotated_lat_lon ; rotated_lat_lon:grid_mapping_name = "rotated_latitude_longitude" ; rotated_lat_lon:grid_north_pole_latitude = 38.f ; rotated_lat_lon:grid_north_pole_longitude = 190.f ; float tas(lon, lat, t) ; tas:standard_name = "air_temperature" ; tas:units = "K" ; tas:cell_methods = "t: mean (interval: 1.0 day)" ; tas:grid_mapping = "rotated_lat_lon" ; data: t = 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, // 12 time values (in hours) 6.5, 7.5, 8.5, 9.5, 10.5, 11.5 ;Field 2:
dimensions: // no time dimension lat = 111 ; lon = 106 ; bounds = 2 ; variables: double time ; // time scalar coordinate // with a different netCDF // variable name time:standard_name = "time" ; // identical standard_name time:units = "days since 2011-12-1" ; // equivalent units time:calendar = "gregorian" ; // equivalent units time:bounds = "time_bnds" ; // bounds present double aux_time_bnds(time, bounds) ; double lat(lat) ; lat:standard_name = "grid_latitude" ; lat:units = "degrees" ; double lon(lon) ; lon:standard_name = "grid_longitude" ; lon:units = "degrees" ; double latitude(grid_longitude, grid_latitude) ; // different dimension order latitude:standard_name = "latitude" ; latitude:units = "degrees_north" ; double longitude(grid_latitude, grid_longitude) ; longitude:standard_name = "longitude" ; longitude:units = "degrees_east" ; char rotated_lat_lon ; // identical grid mapping rotated_lat_lon:grid_mapping_name = "rotated_latitude_longitude" ; rotated_lat_lon:grid_north_pole_latitude = 38.f ; rotated_lat_lon:grid_north_pole_longitude = 190.f ; float tas(lat, lon) ; // different dimension order, // no time dimension tas:standard_name = "air_temperature" ; // identical standard_name tas:units = "C" ; // equivalent units tas:cell_methods = "time: mean (interval 24.0 hours)" ; // equivalent cell methods tas:coordinates = "time" ; // scalar coordinate tas:grid_mapping = "rotated_lat_lon" ; // grid mapping present data: time = 31.52083333; // 1 time value (in days)Aggregation:
dimensions: time = 13 ; // size 13 time dimension lat = 111 ; lon = 106 ; bounds = 2 ; variables: double time ; time:standard_name = "time" ; time:units = "hours since 2012-1-1" ; time:calendar = "standard" ; time:bounds = "time_bnds" ; double aux_time_bnds(time, bounds) ; double lat(lat) ; lat:standard_name = "grid_latitude" ; lat:units = "degrees" ; double lon(lon) ; lon:standard_name = "grid_longitude" ; lon:units = "degrees" ; double latitude(grid_latitude, grid_longitude) ; latitude:standard_name = "latitude" ; latitude:units = "degrees_north" ; double longitude(grid_latitude, grid_longitude) ; longitude:standard_name = "longitude" ; longitude:units = "degrees_east" ; char rotated_lat_lon ; rotated_lat_lon:grid_mapping_name = "rotated_latitude_longitude" ; rotated_lat_lon:grid_north_pole_latitude = 38.f ; rotated_lat_lon:grid_north_pole_longitude = 190.f ; float tas(lon, lat, time) ; tas:standard_name = "air_temperature" ; tas:units = "K" ; tas:cell_methods = "time: mean (interval: 1.0 day)" ; tas:grid_mapping = "rotated_lat_lon" ; data: time = 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, // 13 time values (in hours) 6.5, 7.5, 8.5, 9.5, 10.5, 11.5, 12.5 ;
level
dimension. Note that in this case, the pair
of aggregating axes has two pairs of matching coordinates
(atmosphere_hybrid_sigma_pressure_coordinate
and model_level_number
) and that the pair of matching
coordinates for the non-aggregating time
axis comprise a
dimension coordinate and a scalar coordinate.
Field 1:
dimensions: // no time dimension level = 9 ; latitude = 145 ; longitude = 192 ; bounds = 2 ; variables: double time ; // scalar coordinate time:standard_name = "time" ; time:units = "days since 1860-12-1" ; time:calendar = "gregorian" ; double time_bounds(bounds) ; double sigma(level) ; sigma:standard_name = "atmosphere_hybrid_sigma_pressure_coordinate" ; sigma:units = "1" ; sigma:positive = "down" ; float lat(lat) ; lat:standard_name = "latitude" ; lat:units = "degrees_north" ; float lon(lon) ; longitude:standard_name = "longitude" ; longitude:units = "degrees_east" ; longitude:bounds = "lon_bounds" ; float lon_bounds(lon, bounds) ; int model_level_number(level) ; model_level_number:standard_name = "model_level_number" ; model_level_number:units = "1" ; float eastward_wind(level, lat, lon) ; // no time dimension x_wind:standard_name = "eastward_wind" ; x_wind:units = "m s-1" ; x_wind:coordinates = "time model_level_number" ; x_wind:cell_methods = "time: point" ; data: sigma = 0.2997, 0.2497, 0.1996, 0.14950, 0.0992, 0.0568, 0.02959, 0.0147, 0.0046 ; model_level_number = 11, 12, 13, 14, 15, 16, 17, 18, 19 ;Field 2:
dimensions: time = 1 // size 1 time dimension level = 10 ; latitude = 145 ; longitude = 192 ; bounds = 2 ; variables: double time(time) ; // coordinate time:standard_name = "time" ; time:units = "days since 1860-12-1" ; time:calendar = "gregorian" ; time:bounds = "time_bounds" ; double time_bounds(bounds) ; double sigma(level) ; sigma:standard_name = "atmosphere_hybrid_sigma_pressure_coordinate" ; sigma:units = "1" ; sigma:positive = "down" ; float lat(lat) ; lat:standard_name = "latitude" ; lat:units = "degrees_north" ; float lon(lon) ; longitude:standard_name = "longitude" ; longitude:units = "degrees_east" ; longitude:bounds = "lon_bounds" ; float lon_bounds(lon, bounds) ; int model_level_number(level) ; // auxiliary coordinate // for level dimension model_level_number:standard_name = "model_level_number" ; model_level_number:units = "1" ; float eastward_wind(time, level, lat, lon) ; x_wind:standard_name = "eastward_wind" ; x_wind:units = "m s-1" ; x_wind:coordinates = "time model_level_number" ; x_wind:cell_methods = "time: point" ; data: sigma = 0.997, 0.9749, 0.9304, 0.8698, 0.7922, 0.6995, 0.5995, 0.5045, 0.4221, 0.3546 ; model_level_number = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ;Aggregation:
dimensions: level = 19 ; latitude = 145 ; longitude = 192 ; bounds = 2 ; variables: double time ; time:standard_name = "time" ; time:units = "days since 1860-12-1" ; time:calendar = "gregorian" ; double time_bounds(bounds) ; double sigma(level) ; sigma:standard_name = "atmosphere_hybrid_sigma_pressure_coordinate" ; sigma:units = "1" ; sigma:positive = "down" ; float lat(lat) ; lat:standard_name = "latitude" ; lat:units = "degrees_north" ; float lon(lon) ; longitude:standard_name = "longitude" ; longitude:units = "degrees_east" ; longitude:bounds = "lon_bounds" ; float lon_bounds(lon, bounds) ; int model_level_number(level) ; model_level_number:standard_name = "model_level_number" ; model_level_number:units = "1" ; float eastward_wind(level, lat, lon) ; x_wind:standard_name = "eastward_wind" ; x_wind:units = "m s-1" ; x_wind:coordinates = "time model_level_number" ; x_wind:cell_methods = "time: point" ; data: sigma = 0.997, 0.9749, 0.9304, 0.8698, 0.7922, 0.6995, 0.5995, 0.5045, 0.4221, 0.3546, 0.2997, 0.2497, 0.1996, 0.14950, 0.0992, 0.0568, 0.02959, 0.0147, 0.0046 ; model_level_number = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 ;
region
dimension. Note that in this case, the
aggregating axes have no associated dimension coordinate arrays, but
they do have a logically 1D auxiliary coordinates. Arrays which span
the aggregating axis are simply concatenated, as auxiliary coordinate
array values may be non-monotonic and non-unique.
Field 1:
dimensions: time = 12 ; region = 2 ; // no region coordinate depth = 40 ; lat = 180 ; strlen = 14 ; variables: double time(time) ; time:standard_name = "time" ; time:units = "days since 1860-1-1" ; time:calendar = "gregorian" ; double depth(depth) ; depth:standard_name = "depth" ; depth:units = "m" ; depth:positive = "down" ; double lat(lat) ; lat:standard_name = "latitude" ; lat:units = "degrees_north" ; char geo_region(region, strlen) ; geo_region:standard_name = "region" ; geo_region:long_name = "Ocean Basin" ; float stfmmc(time, region, depth, lat) ; stfmmc:standard_name = "ocean_meridional_overturning_streamfunction" ; stfmmc:units = "m3 s-1" ; stfmmc:coordinates = "geo_region" ; data: geo_region = "atlantic_ocean", "indian_ocean " ;Field 2:
dimensions: time = 12 ; region = 2 ; depth = 40 ; lat = 180 ; strlen = 14 ; variables: double time(time) ; time:standard_name = "time" ; time:units = "days since 1860-1-1" ; time:calendar = "gregorian" ; double depth(depth) ; depth:standard_name = "depth" ; depth:units = "m" ; depth:positive = "down" ; double lat(lat) ; lat:standard_name = "latitude" ; lat:units = "degrees_north" ; char geo_region(region, strlen) ; geo_region:standard_name = "region" ; geo_region:long_name = "Ocean Basin" ; float stfmmc(time, region, depth, lat) ; stfmmc:standard_name = "ocean_meridional_overturning_streamfunction" ; stfmmc:units = "m3 s-1" ; stfmmc:coordinates = "geo_region" ; data: geo_region = "pacific_ocean ", "global_ocean " ;Aggregation:
dimensions: time = 12 ; region = 4 ; depth = 40 ; lat = 180 ; strlen = 14 ; variables: double time(time) ; time:standard_name = "time" ; time:units = "days since 1860-1-1" ; time:calendar = "gregorian" ; double depth(depth) ; depth:standard_name = "depth" ; depth:units = "m" ; depth:positive = "down" ; double lat(lat) ; lat:standard_name = "latitude" ; lat:units = "degrees_north" ; char geo_region(region, strlen) ; geo_region:standard_name = "region" ; geo_region:long_name = "Ocean Basin" ; float stfmmc(time, region, depth, lat) ; stfmmc:standard_name = "ocean_meridional_overturning_streamfunction" ; stfmmc:units = "m3 s-1" ; stfmmc:coordinates = "geo_region" ; data: geo_region = "atlantic_ocean", "indian_ocean ", "pacific_ocean ", "global_ocean " ;
forecast_reference_time
auxiliary coordinate is only
present in one of the fields. If the first field did not have this
auxiliary coordinate then the two fields would be aggregatable.
Field 1:
dimensions: time = 12 ; latitude = 145 ; longitude = 192 ; variables: double time ; time:standard_name = "time" ; time:units = "days since 1860-12-1" ; time:calendar = "gregorian" ; double ref_time(time): sigma:standard_name = "forecast_reference_time" ; time:units = "days since 1860-12-1" ; time:calendar = "gregorian" ; float lat(lat) ; lat:standard_name = "latitude" ; lat:units = "degrees_north" ; float lon(lon) ; longitude:standard_name = "longitude" ; longitude:units = "degrees_east" ; float eastward_wind(time, lat, lon) ; x_wind:standard_name = "eastward_wind" ; x_wind:units = "m s-1" ; x_wind:coordinates = "ref_time" ; data: time = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ;Field 2:
dimensions: time = 12 ; latitude = 145 ; longitude = 192 ; variables: double time ; time:standard_name = "time" ; time:units = "days since 1860-12-1" ; time:calendar = "gregorian" ; float lat(lat) ; lat:standard_name = "latitude" ; lat:units = "degrees_north" ; float lon(lon) ; longitude:standard_name = "longitude" ; longitude:units = "degrees_east" ; float eastward_wind(time, lat, lon) ; // no auxiliary coordinate x_wind:standard_name = "eastward_wind" ; x_wind:units = "m s-1" ; data: time = 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 ;
time
axes' dimension construct coordinate
arrays for share a value.
Field 1:
dimensions: time = 12 ; latitude = 145 ; longitude = 192 ; variables: double time ; time:standard_name = "time" ; time:units = "days since 1860-12-1" ; time:calendar = "gregorian" ; float lat(lat) ; lat:standard_name = "latitude" ; lat:units = "degrees_north" ; float lon(lon) ; longitude:standard_name = "longitude" ; longitude:units = "degrees_east" ; float eastward_wind(time, lat, lon) ; x_wind:standard_name = "eastward_wind" ; x_wind:units = "m s-1" ; data: time = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ; // contains 11Field 2:
dimensions: time = 12 ; latitude = 145 ; longitude = 192 ; variables: double time ; time:standard_name = "time" ; time:units = "days since 1860-12-1" ; time:calendar = "gregorian" ; float lat(lat) ; lat:standard_name = "latitude" ; lat:units = "degrees_north" ; float lon(lon) ; longitude:standard_name = "longitude" ; longitude:units = "degrees_east" ; float eastward_wind(time, lat, lon) ; x_wind:standard_name = "eastward_wind" ; x_wind:units = "m s-1" ; data: time = 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, ; // contains 11