Skip to content

Commit

Permalink
Feature #2565 nccf_laea (#2616)
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnHalleyGotway authored Jul 24, 2023
1 parent 94162cc commit 44cb1d4
Show file tree
Hide file tree
Showing 15 changed files with 608 additions and 550 deletions.
6 changes: 6 additions & 0 deletions .github/jobs/build_docker_image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,9 @@ if [ $? != 0 ]; then
cat ${GITHUB_WORKSPACE}/docker_build.log
exit 1
fi

# Copy the log directory from the image
id=$(docker create ${DOCKERHUB_TAG})
time_command docker cp $id:/met/logs met_logs
mv met_logs/*.log ${GITHUB_WORKSPACE}/.
docker rm -v $id
4 changes: 2 additions & 2 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ jobs:
MET_BASE_REPO: ${{ needs.job_control.outputs.met_base_repo }}
MET_BASE_TAG: ${{ needs.job_control.outputs.met_base_tag }}

- name: Copy Docker build log into logs directory
- name: Copy all build log files into logs directory
if: always()
run: cp ${GITHUB_WORKSPACE}/docker_build.log ${RUNNER_WORKSPACE}/logs/
run: cp ${GITHUB_WORKSPACE}/*.log ${RUNNER_WORKSPACE}/logs/

- name: Push Docker Image
run: .github/jobs/push_docker_image.sh
Expand Down
4 changes: 4 additions & 0 deletions docs/Users_Guide/appendixB.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ The following map projections are currently supported in MET:

* Lambert Conformal Projection

* Lambert Azimuthal Equal Area Projection

* Polar Stereographic Projection (Northern)

* Polar Stereographic Projection (Southern)
Expand Down Expand Up @@ -46,6 +48,8 @@ As an example of specifying a Lambert grid, suppose you have a northern hemisphe
To grid = "lambert 614 428 12.190 -133.459 -95.0 12.19058 6367.47 25.0 N";
For a Lambert Azimuthal Equal Area grid, grid specification strings are not supported.

For a Polar Stereographic grid, the syntax is

.. code-block:: none
Expand Down
4 changes: 0 additions & 4 deletions internal/test_unit/xml/unit_plot_data_plane.xml
Original file line number Diff line number Diff line change
Expand Up @@ -522,9 +522,6 @@
</output>
</test>

<!-- MET #1693 removed support for CF-Compliant LAEA grids.
MET #2565 should restore this supoprt prior to the MET-11.1.0 release.
<test name="plot_data_plane_LAEA_NCCF">
<exec>&MET_BIN;/plot_data_plane</exec>
<param> \
Expand All @@ -538,7 +535,6 @@
<ps>&OUTPUT_DIR;/plot_data_plane/air_temperature_laea_nccf.ps</ps>
</output>
</test>
-->

<test name="plot_data_plane_NCCF_POLAR_STEREO">
<exec>&MET_BIN;/plot_data_plane</exec>
Expand Down
56 changes: 28 additions & 28 deletions src/basic/vx_config/celltype_to_string.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@
////////////////////////////////////////////////////////////////////////


#include <string.h>
using namespace std;

#include "celltype_to_string.h"

#include <string.h>

using namespace std;
#include "celltype_to_string.h"


////////////////////////////////////////////////////////////////////////
Expand All @@ -39,7 +39,7 @@ ConcatString celltype_to_string(const CellType t)

{

const char * s = (const char *) nullptr;
const char * s = (const char *) 0;

switch ( t ) {

Expand Down Expand Up @@ -73,7 +73,7 @@ switch ( t ) {
} // switch


return ConcatString (s);
return ( ConcatString (s) );

}

Expand All @@ -85,33 +85,33 @@ bool string_to_celltype(const char * text, CellType & t)

{

if ( strcmp(text, "integer" ) == 0 ) { t = integer; return true; }
else if ( strcmp(text, "floating_point" ) == 0 ) { t = floating_point; return true; }
else if ( strcmp(text, "boolean" ) == 0 ) { t = boolean; return true; }
else if ( strcmp(text, "cell_mark" ) == 0 ) { t = cell_mark; return true; }
else if ( strcmp(text, "op_add" ) == 0 ) { t = op_add; return true; }

else if ( strcmp(text, "op_multiply" ) == 0 ) { t = op_multiply; return true; }
else if ( strcmp(text, "op_divide" ) == 0 ) { t = op_divide; return true; }
else if ( strcmp(text, "op_subtract" ) == 0 ) { t = op_subtract; return true; }
else if ( strcmp(text, "op_power" ) == 0 ) { t = op_power; return true; }
else if ( strcmp(text, "op_square" ) == 0 ) { t = op_square; return true; }

else if ( strcmp(text, "op_negate" ) == 0 ) { t = op_negate; return true; }
else if ( strcmp(text, "op_store" ) == 0 ) { t = op_store; return true; }
else if ( strcmp(text, "op_recall" ) == 0 ) { t = op_recall; return true; }
else if ( strcmp(text, "identifier" ) == 0 ) { t = identifier; return true; }
else if ( strcmp(text, "user_func" ) == 0 ) { t = user_func; return true; }

else if ( strcmp(text, "builtin_func" ) == 0 ) { t = builtin_func; return true; }
else if ( strcmp(text, "local_var" ) == 0 ) { t = local_var; return true; }
else if ( strcmp(text, "character_string") == 0 ) { t = character_string; return true; }
else if ( strcmp(text, "no_cell_type" ) == 0 ) { t = no_cell_type; return true; }
if ( strcmp(text, "integer" ) == 0 ) { t = integer; return ( true ); }
else if ( strcmp(text, "floating_point" ) == 0 ) { t = floating_point; return ( true ); }
else if ( strcmp(text, "boolean" ) == 0 ) { t = boolean; return ( true ); }
else if ( strcmp(text, "cell_mark" ) == 0 ) { t = cell_mark; return ( true ); }
else if ( strcmp(text, "op_add" ) == 0 ) { t = op_add; return ( true ); }

else if ( strcmp(text, "op_multiply" ) == 0 ) { t = op_multiply; return ( true ); }
else if ( strcmp(text, "op_divide" ) == 0 ) { t = op_divide; return ( true ); }
else if ( strcmp(text, "op_subtract" ) == 0 ) { t = op_subtract; return ( true ); }
else if ( strcmp(text, "op_power" ) == 0 ) { t = op_power; return ( true ); }
else if ( strcmp(text, "op_square" ) == 0 ) { t = op_square; return ( true ); }

else if ( strcmp(text, "op_negate" ) == 0 ) { t = op_negate; return ( true ); }
else if ( strcmp(text, "op_store" ) == 0 ) { t = op_store; return ( true ); }
else if ( strcmp(text, "op_recall" ) == 0 ) { t = op_recall; return ( true ); }
else if ( strcmp(text, "identifier" ) == 0 ) { t = identifier; return ( true ); }
else if ( strcmp(text, "user_func" ) == 0 ) { t = user_func; return ( true ); }

else if ( strcmp(text, "builtin_func" ) == 0 ) { t = builtin_func; return ( true ); }
else if ( strcmp(text, "local_var" ) == 0 ) { t = local_var; return ( true ); }
else if ( strcmp(text, "character_string") == 0 ) { t = character_string; return ( true ); }
else if ( strcmp(text, "no_cell_type" ) == 0 ) { t = no_cell_type; return ( true ); }
//
// nope
//

return false;
return ( false );

}

Expand Down
149 changes: 115 additions & 34 deletions src/libcode/vx_data2d_grib2/data2d_grib2.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ using namespace std;
////////////////////////////////////////////////////////////////////////

double scaled2dbl(int scale_factor, int scale_value);
int parse_int4(g2int);

////////////////////////////////////////////////////////////////////////
//
Expand Down Expand Up @@ -1294,45 +1295,101 @@ void MetGrib2DataFile::read_grib2_grid( gribfield *gfld) {
// Lambert Azimuthal Equal Area
else if ( gfld->igdtnum == 140 ) {

const g2int * p = gfld->igdtmpl;

ScanMode = p[16];
ScanMode = gfld->igdtmpl[16];

// build an LaeaGrib2Data struct with the projection information
LaeaGrib2Data laea;
// build an LaeaData struct with the projection information
LaeaData laea;
laea.name = laea_proj_type;
laea.spheroid_name = "Grib template";
int earth_shape_int = p[0];
if(earth_shape_int == 4) {
laea.radius_km = 0;
laea.equatorial_radius_km = 0.5*6378.1370;
laea.polar_radius_km = 0.5*6356.752314;
laea.is_sphere = false;
}
else {
mlog << Error << "\nMetGrib2DataFile::read_grib2_grid() -> "
<< "unsupported earth shape value of " << earth_shape_int << "!\n\n";
exit(1);

// earth shape
// Reference: https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-2.shtml
int earth_shape_int = gfld->igdtmpl[0];
switch(earth_shape_int){
case 0:
laea.radius_km = 6367.47;
laea.equatorial_radius_km = 0;
laea.polar_radius_km = 0;
laea.is_sphere = true;
break;

case 1:
laea.radius_km = scaled2dbl(gfld->igdtmpl[1], gfld->igdtmpl[2]) / 1000.0;
laea.equatorial_radius_km = 0;
laea.polar_radius_km = 0;
laea.is_sphere = true;
break;

case 2:
laea.radius_km = 0;
laea.equatorial_radius_km = 6378.1600;
laea.polar_radius_km = 6356.7750;
laea.is_sphere = false;
break;

case 3:
laea.radius_km = 0;
laea.equatorial_radius_km = scaled2dbl(gfld->igdtmpl[3], gfld->igdtmpl[4]);
laea.polar_radius_km = scaled2dbl(gfld->igdtmpl[5], gfld->igdtmpl[6]);
laea.is_sphere = false;
break;

case 4:
laea.radius_km = 0;
laea.equatorial_radius_km = 6378.1370;
laea.polar_radius_km = 6356.752314;
laea.is_sphere = false;
break;

case 6:
laea.radius_km = 6371.2290;
laea.equatorial_radius_km = 0;
laea.polar_radius_km = 0;
laea.is_sphere = true;
break;

case 7:
laea.radius_km = 0;
laea.equatorial_radius_km = scaled2dbl(gfld->igdtmpl[3], gfld->igdtmpl[4]) / 1000.0;
laea.polar_radius_km = scaled2dbl(gfld->igdtmpl[5], gfld->igdtmpl[6]) / 1000.0;
laea.is_sphere = false;
break;

default:
mlog << Error << "\nMetGrib2DataFile::read_grib2_grid() -> "
<< "unsupported earth shape value of " << earth_shape_int << "!\n\n";
exit(1);
}
laea.nx = p[7];
laea.ny = p[8];
laea.lat_first = (double)p[9] / 1000000.0;
// TODO: Suspect a bug in g2clib
// laea.lon_first = -1.0*rescale_lon( (double)p[10] / 1000000.0 );

//
// MET#2565:
// Fix a bug when parsing laea.lon_first and laea.central_lon
// in gfld->igdtmpl[10] and gfld->igdtmpl[12] for GRIB2 UKV data.
// These longitudes are negative which the GRIB2C library does not
// parse properly. The parse_int4() function is a workaround to
// reprocesses the data as unsigned chars and check for negative
// values, mimicing logic from the int4() function in wgrib2.
//
// grib_dump: longitudeOfFirstGridPointInDegrees = -17.1171;
// wgrib2: Lon1 2164.600777
// 3-43=129,5,47,201
// g2clib-1.6.0 grid_templates.h
// 3.140: Lambert Azimuthal Equal Area Projection
// BAD? {140, 17, 0, {1,1,4,1,4,1,4,4,4,-4,4,4,4,1,4,4,1} },
// FIX? {140, 17, 0, {1,1,4,1,4,1,4,4,4,-4,4,-4,4,1,4,4,1} },
cout << "TODO LAEA p[10] should be 17.1171 = "<< (double)p[10] / 1000000.0 << "\n";
laea.lon_first = 17.1171;
laea.standard_lat = (double)p[11] / 1000000.0;
laea.central_lon = -1.0*rescale_lon( (double)p[12] / 1000000.0 );
laea.dx_km = (double)p[14] / 1000000.0;
laea.dy_km = (double)p[15] / 1000000.0;
// The grib_dump utility already handles negative longitudes well.
// The wgrib2 utility does NOT when populating gfld->igdtmpl.
// However, the wgrib2 -get_byte and -get_int options do work,
// as shown below:
// wgrib2 ukv_agl_temperature_1.5_12.grib2 \
// -get_byte 3 43 4 -get_int 3 43 1 \
// -get_byte 3 51 4 -get_int 3 51 1
//
// The longitudes are correctly parsed as -17.117129 and -2.5, respectively.
// 1:0:3-43=129,5,47,201:3-43=-17117129:3-51=128,38,37,160:3-51=-2500000
//

laea.nx = gfld->igdtmpl[7];
laea.ny = gfld->igdtmpl[8];
laea.lat_first = (double)gfld->igdtmpl[9] / 1000000.0;
laea.lon_first = -1.0*rescale_lon( (double)parse_int4(gfld->igdtmpl[10]) / 1000000.0);
laea.standard_lat = (double)gfld->igdtmpl[11] / 1000000.0;
laea.central_lon = -1.0*rescale_lon( (double)parse_int4(gfld->igdtmpl[12]) / 1000000.0);
laea.dx_km = (double)gfld->igdtmpl[14] / 1000000.0;
laea.dy_km = (double)gfld->igdtmpl[15] / 1000000.0;

// store the grid information

Expand Down Expand Up @@ -1567,3 +1624,27 @@ double scaled2dbl(int scale_factor, int scale_value) {
}

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

int parse_int4(g2int i) {
unsigned char c[4];
unsigned long n = i;

c[0] = (n >> 24) & 0xFF;
c[1] = (n >> 16) & 0xFF;
c[2] = (n >> 8) & 0xFF;
c[3] = n & 0xFF;

// convert unsigned char to signed integer
int i_val;
if(c[0] & 0x80) {
i_val = -(((c[0] & 0x7f) << 24) + (c[1] << 16) + (c[2] << 8) + c[3]);
}
else {
i_val = (c[0] << 24) + (c[1] << 16) + (c[2] << 8) + c[3];
}

return(i_val);
}

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

Loading

0 comments on commit 44cb1d4

Please sign in to comment.