Skip to content

Commit

Permalink
Per #2118, proposed changes to the vx_data2d_grib library to add supp…
Browse files Browse the repository at this point in the history
…ort for GRIB1 grid template 10 for rotated lat/lon grids.

However this support may not be sufficient.
- It works for the sample COSMO GRIB1 data file we have for testing (lfff03080000).
- However, it basically just treats the rotated lat/lon grid as if it were not rotated.
- The south pole is hard-coded to (lat, lon) = (-90, 0).
- The rotation is hard-coded to 0.
It is not clear how non-default values them would even be encoded in the GDS section.
Before merging these changes, recommend finding or generating additional GRIB1 files on a rotated lat/lon grid for additional development and testing.
  • Loading branch information
JohnHalleyGotway committed Apr 6, 2022
1 parent 71f3d42 commit dbb938c
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 16 deletions.
4 changes: 4 additions & 0 deletions met/src/libcode/vx_data2d_grib/data2d_grib.cc
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,10 @@ bool is_grid_relative(const GribRecord &r) {
else if(r.gds->type == 5) {
res_flag = r.gds->grid_type.stereographic.res_flag;
}
// Rotated LatLon
else if(r.gds->type == 10) {
res_flag = r.gds->grid_type.rot_latlon_grid.res_flag;
}
else {
mlog << Error << "\nis_grid_relative() -> "
<< "Unsupported grid type value: " << r.gds->type
Expand Down
23 changes: 21 additions & 2 deletions met/src/libcode/vx_data2d_grib/grib_classes.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,26 @@ struct Section1_Header { // PDS
////////////////////////////////////////////////////////////////////////


struct LatLon { // Latitude/Longitude Grid
struct LatLon { // Latitude/Longitude Grid

unsigned char lat1[3]; // 11 - 13
unsigned char lon1[3]; // 14 - 16

unsigned char res_flag; // 17

unsigned char lat2[3]; // 18 - 20
unsigned char lon2[3]; // 21 - 23

unsigned char di[2]; // 24 - 25
unsigned char dj[2]; // 26 - 27

unsigned char scan_flag; // 28

unsigned char unused[14]; // 29 - 42

};

struct RotLatLon { // Rotated Latitude/Longitude Grid

unsigned char lat1[3]; // 11 - 13
unsigned char lon1[3]; // 14 - 16
Expand Down Expand Up @@ -282,7 +301,7 @@ struct Gaussian {
union GridType {

struct LatLon latlon_grid; // Latitude/Longitude Grid
// struct RotLatLon rot_latlon_grid; // Rotated Latitude/Longitude Grid
struct RotLatLon rot_latlon_grid; // Rotated Latitude/Longitude Grid
struct Mercator mercator; // Mercator Grid
struct LambertConf lambert_conf; // Lambert Conformal Secant Grid
struct Stereographic stereographic; // Stereographic Grid
Expand Down
111 changes: 97 additions & 14 deletions met/src/libcode/vx_data2d_grib/grib_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ using namespace std;
// grid types from the GDS section
//

static const int latlon_type = 0;
static const int mercator_type = 1;
static const int lambert_type = 3;
static const int stereographic_type = 5;
static const int gaussian_type = 4;
static const int latlon_type = 0;
static const int mercator_type = 1;
static const int lambert_type = 3;
static const int gaussian_type = 4;
static const int stereographic_type = 5;
static const int rotated_latlon_type = 10;



////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -62,7 +64,7 @@ void gds_to_grid(const Section2_Header & gds, Grid & gr)
LambertData lc_data;
StereographicData st_data;
LatLonData ll_data;
//RotatedLatLonData rll_data;
RotatedLatLonData rll_data;
MercatorData mc_data;
GaussianData g_data;

Expand All @@ -84,11 +86,11 @@ if ( gds.type == latlon_type ) {

gr.set(ll_data);

// else if ( gds.type == rotated_latlon_type ) {
//
// gds_to_rotated_latlon(gds, rll_data);
//
// gr.set(rll_data);
} else if ( gds.type == rotated_latlon_type ) {

gds_to_rotated_latlon(gds, rll_data);

gr.set(rll_data);

} else if ( gds.type == mercator_type ) {

Expand Down Expand Up @@ -143,6 +145,7 @@ void gds_to_order(const Section2_Header & gds, int & xdir, int & ydir, int & ord
// Check GDS for the grid type.
// The following Projection types are supported:
// - Lat/Lon
// - Rotated Lat/Lon
// - Mercator
// - Lambert Conformal
// - Polar Stereographic
Expand All @@ -154,6 +157,10 @@ if ( gds.type == latlon_type ) {

scan_flag_to_order(gds.grid_type.latlon_grid.scan_flag, xdir, ydir, order);

} else if ( gds.type == rotated_latlon_type ) {

scan_flag_to_order(gds.grid_type.rot_latlon_grid.scan_flag, xdir, ydir, order);

} else if (gds.type == mercator_type ) {

scan_flag_to_order(gds.grid_type.mercator.scan_flag, xdir, ydir, order);
Expand Down Expand Up @@ -278,10 +285,86 @@ void gds_to_rotated_latlon(const Section2_Header & gds, RotatedLatLonData & data

{

mlog << Error << "\ngds_to_rotated_latlon() -> "
<< "Rotated Lat/Lon grids are not supported in GRIB version 1.\n\n";
int xdir, ydir, order;
double d;

scan_flag_to_order(gds.grid_type.rot_latlon_grid.scan_flag, xdir, ydir, order);

// Store the grid name
data.name = rotated_latlon_proj_type;

//
// Multiply longitude values by -1 since the NCAR code considers
// degrees west to be positive.
//

// Latitude of the bottom left corner
data.rot_lat_ll = min(decode_lat_lon(gds.grid_type.rot_latlon_grid.lat1, 3),
decode_lat_lon(gds.grid_type.rot_latlon_grid.lat2, 3));

// Longitude of the bottom left corner
if ( xdir == 0 ) data.rot_lon_ll = -1.0*rescale_lon(decode_lat_lon(gds.grid_type.rot_latlon_grid.lon1, 3));
else data.rot_lon_ll = -1.0*rescale_lon(decode_lat_lon(gds.grid_type.rot_latlon_grid.lon2, 3));

// Number of points in the Latitudinal (y) direction
data.Nlat = char2_to_int(gds.ny);

// Number of points in the Longitudinal (x) direction
data.Nlon = char2_to_int(gds.nx);

// Check for thinned lat/lon grids
if ( data.Nlon == 65535 ) {

mlog << Error << "\ngds_to_rotated_latlon() -> "
<< "Thinned Lat/Lon grids are not supported for GRIB version 1.\n\n";

exit ( 1 );

}

// Compute latitudinal increment from lat1 and lat2
d = fabs(decode_lat_lon(gds.grid_type.rot_latlon_grid.lat1, 3)
- decode_lat_lon(gds.grid_type.rot_latlon_grid.lat2, 3));

data.delta_rot_lat = d/(data.Nlat);

// If explicitly specified and non-zero, use it
if ( ! all_bits_set(gds.grid_type.rot_latlon_grid.dj, 2) ) {

d = decode_lat_lon(gds.grid_type.rot_latlon_grid.dj, 2);

if ( d > 0 ) data.delta_rot_lat = d;

}

// Compute longitudinal increment from lon1 and lon2
d = fabs(decode_lat_lon(gds.grid_type.rot_latlon_grid.lon1, 3)
- decode_lat_lon(gds.grid_type.rot_latlon_grid.lon2, 3));

data.delta_rot_lon = d/(data.Nlon);

exit ( 1 );
// If explicitly specified and non-zero, use it
if ( ! all_bits_set(gds.grid_type.rot_latlon_grid.di, 2) ) {

d = decode_lat_lon(gds.grid_type.rot_latlon_grid.di, 2);

if ( d > 0 ) data.delta_rot_lon = d;

}

// Location of (rotated) south pole and auxiliary rotation hard-coded to 0

data.true_lat_south_pole = -90.0;

data.true_lon_south_pole = 0.0;

data.aux_rotation = 0.0;

data.dump();

//
// done
//

return;

Expand Down

0 comments on commit dbb938c

Please sign in to comment.