Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature 1574 rotlatlon #1576

Merged
merged 5 commits into from
Nov 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 2 additions & 31 deletions met/docs/Users_Guide/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -452,18 +452,7 @@ using the following entries:

* to_grid = "path"; To regrid both to a grid defined by a file.

* to_grid = "spec"; To define a grid specified as follows:

* lambert Nx Ny lat_ll lon_ll lon_orient D_km R_km standard_parallel_1
[standard_parallel_2] N|S

* stereo Nx Ny lat_ll lon_ll lon_orient D_km R_km lat_scale N|S

* latlon Nx Ny lat_ll lon_ll delta_lat delta_lon

* mercator Nx Ny lat_ll lon_ll lat_ur lon_ur

* gaussian lon_zero Nx Ny
* to_grid = "spec"; To define a grid specification string, as described in :ref:`appendixB`.

* The "vld_thresh" entry specifies a proportion between 0 and 1 to define
the required ratio of valid data points. When regridding, compute
Expand Down Expand Up @@ -4004,25 +3993,7 @@ WWMCARegridConfig_default

**to_grid**

Specify the grid to which the data should be interpolated in one of the
following ways:

* Name ("GNNN" where NNN indicates the three digit NCEP grid number)

* lambert Nx Ny lat_ll lon_ll lon_orient D_km R_km standard_parallel_1
[standard_parallel_2] N|S

* stereo Nx Ny lat_ll lon_ll lon_orient D_km R_km lat_scale N|S

* latlon Nx Ny lat_ll lon_ll delta_lat delta_lon

* mercator Nx Ny lat_ll lon_ll lat_ur lon_ur

* gaussian lon_zero Nx Ny

.. code-block:: none

to_grid = "lambert 614 428 12.190 -133.459 -95.0 12.19058 6367.47 25.0 N";
Please see the description of the "to_grid" entry in the "regrid" dictionary above.

**NetCDF output information**

Expand Down
61 changes: 60 additions & 1 deletion met/docs/Users_Guide/appendixB.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,69 @@ The following map projections are currently supported in MET:

* Gaussian Projection

Grid Specification Strings
__________________________

Several configuration file and command line options support the definition of grids as a grid specification string. A description of the that string for each of the supported grid types is provided below.

To specify a Lambert Grid, the syntax is

.. code-block:: none

lambert Nx Ny lat_ll lon_ll lon_orient D_km R_km standard_lat_1 [ standard_lat_2 ] N|S

Here, **Nx** and **Ny** are the number of points in, respectively, the **x** and **y** grid directions. These two numbers give the overall size of the grid. **lat_ll** and **lon_ll** are the latitude and longitude, in degrees, of the lower left point of the grid. North latitude and east longitude are considered positive. **lon_orient** is the orientation longitude of the grid. It’s the meridian of longitude that’s parallel to one of the vertical grid directions. **D_km** and **R_km** are the grid resolution and the radius of the Earth, both in kilometers. **standard_lat_1** and **standard_lat_2** are the standard parallels of the Lambert projection. If the two latitudes are the same, then only one needs to be given. **N|S** means to write either **N** or **S** depending on whether the Lambert projection is from the north pole or the south pole.

As an example of specifying a Lambert grid, suppose you have a northern hemisphere Lambert grid with 614 points in the x direction and 428 points in the y direction. The lower left corner of the grid is at latitude :math:`12.190^\circ` north and longitude :math:`133.459^\circ` west. The orientation longitude is :math:`95^\circ` west. The grid spacing is :math:`12.19058^\circ` km. The radius of the Earth is the default value used in many grib files: 6367.47 km. Both standard parallels are at :math:`25^\circ` north. To specify this grid in the config file, you would write

.. code-block:: none

To grid = "lambert 614 428 12.190 -133.459 -95.0 12.19058 6367.47 25.0 N";

For a Polar Stereographic grid, the syntax is

.. code-block:: none

stereo Nx Ny lat_ll lon_ll lon_orient D_km R_km lat_scale N|S

Here, **Nx, Ny, lat_ll, lon_ll, lon_orient, D_km** and **R_km** have the same meaning as in the Lambert case. **lat_scale** is the latitude where the grid scale **D_km** is true, while **N|S** means to write either **N** or **S** depending on whether the stereographic projection is from the north pole or the south pole.

For Plate Carrée (i.e. Lat/Lon) grids, the syntax is

.. code-block:: none

latlon Nx Ny lat_ll lon_ll delta_lat delta_lon

The parameters **Nx, Ny, lat_ll** and **lon_ll** are as before. **delta_lat** and **delta_lon** are the latitude and longitude increments of the grid—i.e., the change in latitude or longitude between one grid point and an adjacent grid point.

For a Rotated Plate Carrée (i.e. Rotated Lat/Lon) grids, the syntax is

.. code-block:: none

rotlatlon Nx Ny lat_ll lon_ll delta_lat delta_lon true_lat_sp true_lon_sp aux_rotation

The parameters **Nx, Ny, lat_ll, lon_ll, delta_lat,** and **delta_lon** are as before. **true_lat_sp** and **true_lon_sp** are the latitude and longitude for the south pole. **aux_rotation** is the auxilary rotation in degrees.

For a Mercator grid, the syntax is

.. code-block:: none

mercator Nx Ny lat_ll lon_ll lat_ur lon_ur

The parameters **Nx, Ny, lat_ll** and **lon_ll** are again as before, while **lat_ur** and **lon_ur** are the latitude and longitude of the upper right corner of the grid.

For a Gaussian grid, the syntax is

.. code-block:: none

gaussian lon_zero Nx Ny

The parameters **Nx** and **Ny** are as before, while **lon_zero** defines the first longitude.

Grids
_____

All of NCEP's pre-defined grids that reside on one of the projections listed above are implemented in MET. The user may specify one of these NCEP grids in the configuration files as "GNNN" where NNN is the 3-digit NCEP grid number. Defining a new masking grid in MET would involve modifying the vx_data_grids library and recompiling.
The majority of NCEP's pre-defined grids that reside on one of the projections listed above are implemented in MET. The user may specify one of these NCEP grids in the configuration files as "GNNN" where NNN is the 3-digit NCEP grid number. Defining a new masking grid in MET would involve modifying the vx_data_grids library and recompiling.

Please see `NCEP's website for a description and plot of these predefined grids <http://www.nco.ncep.noaa.gov/pmb/docs/on388/tableb.html>`_.

Expand Down
40 changes: 1 addition & 39 deletions met/docs/Users_Guide/appendixE.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,45 +43,7 @@ Now let’s talk about the details of the config file. The config file has the s

To grid = "G218";

and that will work. Failing that, you must give the parameters that specify the grid and it’s projection. Four projections are supported: Lambert Conformal, Polar Stereographic, Plate Carrée, and Mercator.

To specify a Lambert Grid, the syntax is

.. code-block:: none

lambert Nx Ny lat_ll lon_ll lon_orient D_km R_km standard_lat_1 [ standard_lat_2 ] N|S

Here, **Nx** and **Ny** are the number of points in, respectively, the **x** and **y** grid directions. These two numbers give the overall size of the grid. **lat_ll** and **lon_ll** are the latitude and longitude, in degrees, of the lower left point of the grid. North latitude and east longitude are considered positive. **lon_orient** is the orientation longitude of the grid. It’s the meridian of longitude that’s parallel to one of the vertical grid directions. **D_km** and **R_km** are the grid resolution and the radius of the Earth, both in kilometers. **standard_lat_1** and **standard_lat_2** are the standard parallels of the Lambert projection. If the two latitudes are the same, then only one needs to be given. **N|S** means to write either **N** or **S** depending on whether the Lambert projection is from the north pole or the south pole.

As an example of specifying a Lambert grid, suppose you have a northern hemisphere Lambert grid with 614 points in the x direction and 428 points in the y direction. The lower left corner of the grid is at latitude :math:`12.190^\circ` north and longitude :math:`133.459^\circ` west. The orientation longitude is :math:`95^\circ` west. The grid spacing is :math:`12.19058^\circ` km. The radius of the Earth is the default value used in many grib files: 6367.47 km. Both standard parallels are at :math:`25^\circ` north. To specify this grid in the config file, you would write

.. code-block:: none

To grid = "lambert 614 428 12.190 -133.459 -95.0 12.19058 6367.47 25.0 N";

For a Polar Stereographic grid, the syntax is

.. code-block:: none

Nx Ny lat_ll lon_ll lon_orient D_km R_km lat_scale N|S

Here, **Nx, Ny, lat_ll, lon_ll, lon_orient, D_km** and **R_km** have the same meaning as in the Lambert case. **lat_scale** is the latitude where the grid scale **D_km** is true, while **N|S** means to write either **N** or **S** depending on whether the stereographic projection is from the north pole or the south pole.

For Plate Carrée grids, the syntax is

.. code-block:: none

latlon Nx Ny lat_ll lon_ll delta_lat delta_lon

The parameters **Nx, Ny, lat_ll** and **lon_ll** are as before. **delta_lat** and **delta_lon** are the latitude and longitude increments of the grid—i.e., the change in latitude or longitude between one grid point and an adjacent grid point.

For a Mercator grid, the syntax is

.. code-block:: none

mercator Nx Ny lat_ll lon_ll lat_ur lon_ur

The parameters **Nx, Ny, lat_ll** and **lon_ll** are again as before, while **lat_ur** and **lon_ur** are the latitude and longitude of the upper right corner of the grid.
and that will work. Failing that, you must give the parameters that specify the grid and it’s projection. Please refer the description of the grid specification strings in :ref:`appendixB`.

Thankfully, the rest of the parameters in the config file are easier to specify.

Expand Down
63 changes: 62 additions & 1 deletion met/docs/Users_Guide/appendixF.rst
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,68 @@ The data must be loaded into a 2D NumPy array named **met_data**. In addition th
}


In the dictionary, valid time, initialization time, lead time and accumulation time (if any) must be indicated by strings. Valid and initialization times must be given in YYYYMMDD[_HH[MMSS]] format, and lead and accumulation times must be given in HH[MMSS] format, where the square brackets indicate optional elements. The dictionary must also include strings for the name, long_name, level, and units to describe the data. The rest of the **attrs** dictionary gives the grid size and projection information in the same format that is used in the netCDF files written out by the MET tools. Note that the **grid** entry in the **attrs** dictionary is itself a dictionary.
In the dictionary, valid time, initialization time, lead time and accumulation time (if any) must be indicated by strings. Valid and initialization times must be given in YYYYMMDD[_HH[MMSS]] format, and lead and accumulation times must be given in HH[MMSS] format, where the square brackets indicate optional elements. The dictionary must also include strings for the name, long_name, level, and units to describe the data. The rest of the **attrs** dictionary gives the grid size and projection information in the same format that is used in the netCDF files written out by the MET tools. Those entries are also listed below. Note that the **grid** entry in the **attrs** dictionary is itself a dictionary.

The supported grid **type** strings are described below:

• **Lambert Conformal** grid dictionary entries:

• type ("Lambert Conformal")
• name (string)
• hemisphere (string: "N" or "S")
• scale_lat_1, scale_lat_2 (double)
• lat_pin, lon_pin, x_pin, y_pin (double)
• lon_orient (double)
• d_km, r_km (double)
• nx, ny (int)

• **Polar Stereographic** grid dictionary entries:

• type ("Polar Stereographic")
• name (string)
• hemisphere (string: "N" or "S")
• scale_lat (double)
• lat_pin, lon_pin, x_pin, y_pin (double)
• lon_orient (double)
• d_km, r_km (double)
• nx, ny (int)

• **Mercator** grid dictionary entries:

• type ("Mercator")
• name (string)
• lat_ll (double)
• lon_ll (double)
• lat_ur (double)
• lon_ur (double)
• nx, ny (int)

• **LatLon** grid dictionary entries:

• type ("LatLon")
• name (string)
• lat_ll, lon_ll (double)
• delta_lat, delta_lon (double)
• Nlat, Nlon (int)

• **Rotated LatLon** grid dictionary entries:

• type ("Rotated LatLon")
• name (string)
• rot_lat_ll, rot_lon_ll (double)
• delta_rot_lat, delta_rot_lon (double)
• Nlat, Nlon (int)
• true_lat_south_pole, true_lon_south_pole (double)
• aux_rotation (double)

• **Gaussian** grid dictionary entries:

• type ("Gaussian")
• name (string)
• lon_zero (double)
• nx, ny (int)

Additional information about supported grids can be found in :ref:`appendixB`.

**Using Xarray Objects**

Expand Down
106 changes: 100 additions & 6 deletions met/src/libcode/vx_grid/find_grid_by_name.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ static bool parse_lambert_grid(const StringArray &, Grid &);

static bool parse_latlon_grid(const StringArray &, Grid &);

static bool parse_rotlatlon_grid(const StringArray &, Grid &);

static bool parse_stereographic_grid(const StringArray &, Grid &);

static bool parse_mercator_grid(const StringArray &, Grid &);
Expand Down Expand Up @@ -207,12 +209,13 @@ bool status = false;
// parse supported projection types
//

if ( strcasecmp(grid_strings[0].c_str(), "lambert") == 0 ) status = parse_lambert_grid(grid_strings, g);
else if ( strcasecmp(grid_strings[0].c_str(), "latlon") == 0 ) status = parse_latlon_grid(grid_strings, g);
else if ( strcasecmp(grid_strings[0].c_str(), "stereo") == 0 ) status = parse_stereographic_grid(grid_strings, g);
else if ( strcasecmp(grid_strings[0].c_str(), "mercator") == 0 ) status = parse_mercator_grid(grid_strings, g);
else if ( strcasecmp(grid_strings[0].c_str(), "gaussian") == 0 ) status = parse_gaussian_grid(grid_strings, g);
else status = false;
if ( strcasecmp(grid_strings[0].c_str(), "lambert") == 0 ) status = parse_lambert_grid(grid_strings, g);
else if ( strcasecmp(grid_strings[0].c_str(), "latlon") == 0 ) status = parse_latlon_grid(grid_strings, g);
else if ( strcasecmp(grid_strings[0].c_str(), "rotlatlon") == 0 ) status = parse_rotlatlon_grid(grid_strings, g);
else if ( strcasecmp(grid_strings[0].c_str(), "stereo") == 0 ) status = parse_stereographic_grid(grid_strings, g);
else if ( strcasecmp(grid_strings[0].c_str(), "mercator") == 0 ) status = parse_mercator_grid(grid_strings, g);
else if ( strcasecmp(grid_strings[0].c_str(), "gaussian") == 0 ) status = parse_gaussian_grid(grid_strings, g);
else status = false;

//
// done
Expand Down Expand Up @@ -546,6 +549,97 @@ return ( true );
////////////////////////////////////////////////////////////////////////


bool parse_rotlatlon_grid(const StringArray &grid_strings, Grid & g)

{

Grid * ToGrid = (Grid *) 0;

RotatedLatLonData rdata;

const int N = grid_strings.n_elements();

if ( N != 10 ) {

mlog << Error << "\nparse_rotlatlon_grid() -> "
<< "rotatedlatlon grid spec should have 10 entries\n\n";

exit ( 1 );

}

int j;
int Nx, Ny;
double lat_ll, lon_ll, delta_lat, delta_lon;
double true_lat_sp, true_lon_sp, aux_rot;


j = 1;

//
// get info from the strings
//

Nx = atoi(grid_strings[j++].c_str());
Ny = atoi(grid_strings[j++].c_str());

lat_ll = atof(grid_strings[j++].c_str());
lon_ll = atof(grid_strings[j++].c_str());

delta_lat = atof(grid_strings[j++].c_str());
delta_lon = atof(grid_strings[j++].c_str());

true_lat_sp = atof(grid_strings[j++].c_str());
true_lon_sp = atof(grid_strings[j++].c_str());
aux_rot = atof(grid_strings[j++].c_str());

//
// load up the struct
//

rdata.name = "To (rotlatlon)";

rdata.rot_lat_ll = lat_ll;
rdata.rot_lon_ll = lon_ll;

rdata.delta_rot_lat = delta_lat;
rdata.delta_rot_lon = delta_lon;

rdata.Nlat = Ny;
rdata.Nlon = Nx;

rdata.true_lat_south_pole = true_lat_sp;
rdata.true_lon_south_pole = true_lon_sp;

rdata.aux_rotation = aux_rot;

if ( !west_longitude_positive ) {

rdata.rot_lon_ll *= -1.0;
rdata.true_lon_south_pole *= -1.0;

}

ToGrid = new Grid ( rdata );

g = *ToGrid;

if ( ToGrid ) { delete ToGrid; ToGrid = (Grid *) 0; }


//
// done
//


return ( true );

}


////////////////////////////////////////////////////////////////////////


bool parse_mercator_grid(const StringArray &grid_strings, Grid & g)

{
Expand Down
15 changes: 15 additions & 0 deletions test/xml/unit_regrid.xml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,21 @@
</output>
</test>

<test name="regrid_data_plane_GFS_ROTLATLON_GRID_SPEC">
<exec>&MET_BIN;/regrid_data_plane</exec>
<param> \
&DATA_DIR_MODEL;/grib1/gfs/gfs_2012040900_F036.grib \
"rotlatlon 420 408 -7.542 8.326 0.035999 0.035999 -34.515 -22.179 0" \
&OUTPUT_DIR;/regrid/regrid_data_plane_GFS_TO_ROTLATLON_GRID_SPEC.nc \
-field 'name="TMP"; level="P500";' \
-method BILIN -width 2 \
-v 1
</param>
<output>
<grid_nc>&OUTPUT_DIR;/regrid/regrid_data_plane_GFS_TO_ROTLATLON_GRID_SPEC.nc</grid_nc>
</output>
</test>

<test name="regrid_data_plane_GFS_TO_HMT_BILIN">
<exec>&MET_BIN;/regrid_data_plane</exec>
<param> \
Expand Down