MAPL Grids File Spec - GEOS-ESM/MAPL GitHub Wiki

This describes the NetCDF file format that is emitted and understood when reading by the common IO layer used by History/ExtData and any utility that uses the same IO layer that can be translated to and from an ESMF Grid. The file metadata consists of two parts, one is grid specific, i.e. a file on say a Lat-Lon grid will have a different metadata than say a Tripolar grid. Some metadata would be consistent however, that being the time and any sort of non-horizontal levels.

All gridded output and input in GEOS uses the convention that in variables, the first indices represent the horizontal (this may be 2 of 3 depending on the grid type), then follows "levels", then finally time.

MAPL supports 4 rectilinear grid types. A single tile (this would be your Lat-Lon, Tripolar, or generic XY grid) and a multi-tile grid (Cubed-Sphere), where the grid is actual a set of rectilinear grids that have connections to the other tiles. In the literature and in other frameworks is sometimes referred to as a "mosaic".

Lat-Lon

A Lat-Lon grid is a 2D dimension grid where the longitude is fixed as the 2nd index of the array varies and the latitude is fixed as the 1st index varies, hence why the coordinates can be 1-D variables. In other words the longitude has a 1 to 1 relationship between the 1st index, and the latitude a 1 to 1 relationship to the 2nd index.

dimensions:
        lon = 180 ;
        lat = 91 ;
        time = UNLIMITED ; // (1 currently)
variables:
        double lon(lon) ;
                lon:long_name = "longitude" ;
                lon:units = "degrees_east" ;
        double lat(lat) ;
                lat:long_name = "latitude" ;
                lat:units = "degrees_north" ;
        int time(time) ;
                time:long_name = "time" ;
                time:units = "minutes since 2000-04-15 00:00:00" ;
                time:time_increment = 60000 ;
                time:begin_date = 20000415 ;
        float example_variable(time, lat, lon) ;
                PS:long_name = "surface_pressure" ;
                PS:units = "Pa" ;
                PS:_FillValue = 1.e+15f ;
                PS:missing_value = 1.e+15f ;
                PS:fmissing_value = 1.e+15f ;
                PS:scale_factor = 1.f ;
                PS:add_offset = 0.f ;
                PS:standard_name = "surface_pressure" ;
                PS:vmin = -1.e+15f ;
                PS:vmax = 1.e+15f ;
                PS:valid_range = -1.e+15f, 1.e+15f ;

The latitude and longitude arrays are double precision MONOTONICALLY INCREASING values representing the latitudes or longitudes in degrees that either span the entire globe or can be a regional patch.

Cubed-Sphere

Tripolar

The tripolar grid is a generic non-global rectilinear grid with a monopole at the pole. Since the latitude and longitude both vary with both the 1st and 2nd horizontal index, the coordinates must be stored as 2D dimensional arrays. We also output the corners of the grid as standard which necessitates an extra 2 dimensions to store the corner values

dimensions:
        XCdim = 73 ;
        Xdim = 72 ;
        YCdim = 37 ;
        Ydim = 36 ;
        time = UNLIMITED ; // (1 currently)
variables:
        double Xdim(Xdim) ;
                Xdim:long_name = "Fake Longitude for GrADS Compatibility" ;
                Xdim:units = "degrees_east" ;
        double Ydim(Ydim) ;
                Ydim:long_name = "Fake Latitude for GrADS Compatibility" ;
                Ydim:units = "degrees_north" ;
        double lons(Ydim, Xdim) ;
                lons:long_name = "longitude" ;
                lons:units = "degrees_east" ;
        double lats(Ydim, Xdim) ;
                lats:long_name = "latitude" ;
                lats:units = "degrees_north" ;
        double corner_lons(YCdim, XCdim) ;
                corner_lons:long_name = "longitude" ;
                corner_lons:units = "degrees_east" ;
        double corner_lats(YCdim, XCdim) ;
                corner_lats:long_name = "latitude" ;
                corner_lats:units = "degrees_north" ;
        float time(time) ;
                time:begin_date = 20000416 ;
                time:begin_time = 3000 ;
                time:long_name = "time" ;
                time:time_increment = 10000 ;
                time:units = "minutes since 2000-04-16 00:30:00" ;
        float example_variable(time, Ydim, Xdim) ;
                AREA:_FillValue = 1.e+15f ;
                AREA:add_offset = 0.f ;
                AREA:fmissing_value = 1.e+15f ;
                AREA:long_name = "MOM_ocean_area_at_t-points" ;
                AREA:missing_value = 1.e+15f ;
                AREA:regrid_method = "bilinear" ;
                AREA:scale_factor = 1.f ;
                AREA:standard_name = "MOM_ocean_area_at_t-points" ;
                AREA:units = "m+2" ;
                AREA:valid_range = -1.e+15f, 1.e+15f ;
                AREA:vmax = 1.e+15f ;
                AREA:vmin = -1.e+15f ;
// global attributes:
                :grid_type = "Tripolar" ;

Generic XY grid (Currently being implemented)

This is a plain old regional rectilinear grid (so no assumptions are made about periodicity, pole handling or any special options like that). The latitude and longitude vary as a function of both horizontal indices so the coordinates but be 2D arrays and when represented as an ESMF Grid no periodic or special pole handling is presumed. It looks a lot like the tripolar but has a global attribute to distinguish it from a Tripolar grid. Note this NOT a regional lat/lon grid, as the lat/lon grid has an assumption about the latitude and longitude and their relation to the index space that is not appropriate in the more general case.

dimensions:
        XCdim = 73 ;
        Xdim = 72 ;
        YCdim = 37 ;
        Ydim = 36 ;
        time = UNLIMITED ; // (1 currently)
variables:
        double Xdim(Xdim) ;
                Xdim:long_name = "Fake Longitude for GrADS Compatibility" ;
                Xdim:units = "degrees_east" ;
        double Ydim(Ydim) ;
                Ydim:long_name = "Fake Latitude for GrADS Compatibility" ;
                Ydim:units = "degrees_north" ;
        double lons(Ydim, Xdim) ;
                lons:long_name = "longitude" ;
                lons:units = "degrees_east" ;
        double lats(Ydim, Xdim) ;
                lats:long_name = "latitude" ;
                lats:units = "degrees_north" ;
        double corner_lons(YCdim, XCdim) ;
                corner_lons:long_name = "longitude" ;
                corner_lons:units = "degrees_east" ;
        double corner_lats(YCdim, XCdim) ;
                corner_lats:long_name = "latitude" ;
                corner_lats:units = "degrees_north" ;
        float time(time) ;
                time:begin_date = 20000416 ;
                time:begin_time = 3000 ;
                time:long_name = "time" ;
                time:time_increment = 10000 ;
                time:units = "minutes since 2000-04-16 00:30:00" ;
        float example_variable(time, Ydim, Xdim) ;
                AREA:_FillValue = 1.e+15f ;
                AREA:add_offset = 0.f ;
                AREA:fmissing_value = 1.e+15f ;
                AREA:long_name = "MOM_ocean_area_at_t-points" ;
                AREA:missing_value = 1.e+15f ;
                AREA:regrid_method = "bilinear" ;
                AREA:scale_factor = 1.f ;
                AREA:standard_name = "MOM_ocean_area_at_t-points" ;
                AREA:units = "m+2" ;
                AREA:valid_range = -1.e+15f, 1.e+15f ;
                AREA:vmax = 1.e+15f ;
                AREA:vmin = -1.e+15f ;
// global attributes:
                :grid_type = "XY" ;

Level Metadata (common across all grid formats)

Time Metadata (common across all grid formats)