Most CMIP6 ocean models use a curvilinear grid, which means an ocean variable (e.g. wfo
) will be defined as follows:
netcdf wfo_Omon_HadGEM3-GC31-LL_piControl_r1i1p1f1_gn_225001-234912 {
dimensions:
time = UNLIMITED ; // (1200 currently)
bnds = 2 ;
j = 330 ;
i = 360 ;
vertices = 4 ;
variables:
double time(time) ;
time:bounds = "time_bnds" ;
time:units = "days since 1850-01-01" ;
time:calendar = "360_day" ;
time:axis = "T" ;
time:long_name = "time" ;
time:standard_name = "time" ;
double time_bnds(time, bnds) ;
int j(j) ;
j:units = "1" ;
j:long_name = "cell index along second dimension" ;
int i(i) ;
i:units = "1" ;
i:long_name = "cell index along first dimension" ;
float latitude(j, i) ;
latitude:standard_name = "latitude" ;
latitude:long_name = "latitude" ;
latitude:units = "degrees_north" ;
latitude:missing_value = 1.e+20f ;
latitude:_FillValue = 1.e+20f ;
latitude:bounds = "vertices_latitude" ;
float longitude(j, i) ;
longitude:standard_name = "longitude" ;
longitude:long_name = "longitude" ;
longitude:units = "degrees_east" ;
longitude:missing_value = 1.e+20f ;
longitude:_FillValue = 1.e+20f ;
longitude:bounds = "vertices_longitude" ;
float wfo(time, j, i) ;
...
You'll notice that wfo(time, j, i)
where j
is defined as the cell index along second dimension
and i
the cell index along first dimension
.
You can go ahead and use these dimension names to collapse coordinates (or to do whatever other calculations you are doing along an axis):
In [ ]:
import warnings
warnings.filterwarnings('ignore')
import iris
In [21]:
good_file = '/g/data1b/oi10/replicas/CMIP6/CMIP/MOHC/HadGEM3-GC31-LL/piControl/r1i1p1f1/Omon/wfo/gn/v20190628/wfo_Omon_HadGEM3-GC31-LL_piControl_r1i1p1f1_gn_225001-234912.nc'
good_cube = iris.load_cube(good_file, 'water_flux_into_sea_water')
In [22]:
print(good_cube.summary(shorten=True))
In [24]:
spatial_mean = good_cube.collapsed(['cell index along second dimension', 'cell index along first dimension'], iris.analysis.MEAN)
In [26]:
print(spatial_mean.summary(shorten=True))
In CMIP6, however, some groups have not defined the j
and i
dimensions (I didn't notice this in CMIP5). e.g:
netcdf wfo_Omon_CNRM-CM6-1_piControl_r1i1p1f2_gn_185001-234912 {
dimensions:
axis_nbounds = 2 ;
x = 362 ;
y = 294 ;
nvertex = 4 ;
time = UNLIMITED ; // (6000 currently)
variables:
double lat(y, x) ;
lat:standard_name = "latitude" ;
lat:long_name = "Latitude" ;
lat:units = "degrees_north" ;
lat:bounds = "bounds_lat" ;
double lon(y, x) ;
lon:standard_name = "longitude" ;
lon:long_name = "Longitude" ;
lon:units = "degrees_east" ;
lon:bounds = "bounds_lon" ;
double bounds_lon(y, x, nvertex) ;
double bounds_lat(y, x, nvertex) ;
double time(time) ;
time:axis = "T" ;
time:standard_name = "time" ;
time:long_name = "Time axis" ;
time:calendar = "gregorian" ;
time:units = "days since 1850-01-01 00:00:00" ;
time:time_origin = "1850-01-01 00:00:00" ;
time:bounds = "time_bounds" ;
double time_bounds(time, axis_nbounds) ;
float wfo(time, y, x) ;
...
This means you can't refer to the spatial dimensions by name, which is very annoying.
In [29]:
bad_file = '/g/data1b/oi10/replicas/CMIP6/CMIP/CNRM-CERFACS/CNRM-CM6-1/piControl/r1i1p1f2/Omon/wfo/gn/v20180814/wfo_Omon_CNRM-CM6-1_piControl_r1i1p1f2_gn_185001-234912.nc'
bad_cube = iris.load_cube(bad_file, 'water_flux_into_sea_water')
In [30]:
print(bad_cube.summary(shorten=True))